最近在改写kibana,碰到了验证登录的问题。问题是这样子的,nginx设置了basic认证,然后客户端访问kibana的时候总是会弹出登录框,输入用户名和密码,现在要改写这个登陆框,用bootstrap来模拟一下登录验证。

最终效果:

解决方案:首先看到请求的返回status是401,也就是未授权,可以自己百度一下 `basic authentication`。我们需要在node端把401的错误码改成其他的,我这里改成了403。红色部分是我后来加上的,文件路径: `src/server/plugins/elasticsearch/lib/create_proxy.js`。这样就不会弹出难看的认证框了。

  1. var createAgent = require('./create_agent');
  2. var mapUri = require('./map_uri');
  3. module.exports = function createProxy(server, method, route, opts) {
  4. opts = opts || {};
  5. var options = {
  6. method: method,
  7. path: route,
  8. handler: {
  9. proxy: {
  10. mapUri: mapUri(server, opts.prefix),
  11. passThrough: true,
  12. agent: createAgent(server),
  13. onResponse:function(err, res, request, reply, settings, ttl){
  14. if(res.statusCode==401){
  15. res.statusCode =403;
  16. }
  17. reply(res);
  18. }
  19. }
  20. }
  21. };
  22. if (opts && opts.config) options.config = opts.config;
  23. server.route(options);
  24. };

解决了nodejs端的状态码问题,现在该处理前端的展示方面了。

看了kibana源码,这里引用了angularjs,那就好办了,我们可以利用$httpProvider这个服务来写一个拦截器。然后在request的时候,把本地存储的用户名和密码写到header中去,就模拟了basic验证。文件路径:src/kibana/plugins/kibana/index.js

  1. // ensure that the kibana module requires ui.bootstrap
    require('modules')
    .get('kibana', ['ui.bootstrap','ngCookies'])
    .config(function ($tooltipProvider) {
    $tooltipProvider.setTriggers({ 'mouseenter': 'mouseleave click' });
    })
    .factory('HttpInterceptorFactory', ['$rootScope', '$cookieStore', '$q', function ($rootScope, $cookieStore, $q) {
    return {
    'request': function (httpConfig) {
    var up = $cookieStore.get('usernameandpassword');
  2.  
  3. up && (httpConfig.headers.Authorization = "Basic " + up);
  4.  
  5. return httpConfig;
    }
    };
    }])
    .config(['$httpProvider', function ($httpProvider) {
    $httpProvider.interceptors.push('HttpInterceptorFactory');
    }])
    .controller('LoginController',function($scope,$cookieStore,$modalInstance){
    $scope.username="";
    $scope.password="";
    $scope.ok = function (user,psw) {
    $cookieStore.put("usernameandpassword", btoa(user +":"+psw));
    location.reload();
    };
    })
    .directive('kibana', function (Private, $rootScope,$timeout, $cookieStore,$injector, Promise, config, kbnSetup,$modal) {
    return {
    template: require('text!plugins/kibana/kibana.html'),
    controllerAs: 'kibana',
    controller: function ($scope) {
    var _ = require('lodash');
    var self = $rootScope.kibana = this;
    var notify = new Notifier({ location: 'Kibana' });
  6.  
  7. // this is the only way to handle uncaught route.resolve errors
    $rootScope.$on('$routeChangeError', function (event, next, prev, err) {
    if(err.origError.status==403){
    // location.hash="#/passport/login";
    self.doLogin();
    return;
    }
    notify.fatal(err);
    });
  8.  
  9. self.doLogin = function(){
    var modalInstance = $modal.open({
    template: require('text!plugins/kibana/login.html'),
    controller: 'LoginController',
    size: 'sm',
    backdrop:'static'
    });
    modalInstance.result.then(function (selectedItem) {
  10.  
  11. }, function () {
    $log.info('Modal dismissed at: ' + new Date());
    });
    }
  12.  
  13. // run init functions before loading the mixins, so that we can ensure that
    // the environment is ready for them to get and use their dependencies
    self.ready = Promise.all([ kbnSetup(), config.init() ])
    .then(function () {
    // load some "mixins"
    var mixinLocals = { $scope: $scope, notify: notify };
    $injector.invoke(require('plugins/kibana/_init'), self, mixinLocals);
    $injector.invoke(require('plugins/kibana/_apps'), self, mixinLocals);
    $injector.invoke(require('plugins/kibana/_timepicker'), self, mixinLocals);
  14.  
  15. $scope.setupComplete = true;
    });
    }
    };
    });
  1. <div class="modal-header">
  2. <h3 class="modal-title">Login In</h3>
  3. </div>
  4.  
  5. <div class="modal-body">
  6. <div class="form-group">
  7. <label >Username</label>
  8. <input style="border:1px solid;" type="text" ng-model="username" class="form-control" placeholder="Username">
  9. </div>
  10. <div class="form-group">
  11. <label >Password</label>
  12. <input style="border:1px solid;" type="password" ng-model="password" class="form-control" placeholder="Password">
  13. </div>
  14. </div>
  15. <div class="modal-footer">
  16. <button class="btn btn-primary" ng-click="ok(username,password)">Login</button>
  17. </div>

大功告成。我使用的kibana的版本是4.2.0,enjoy it。

kibana去掉丑陋的basic验证框,用自定义验证代替。的更多相关文章

  1. SpringBoot-表单验证-统一异常处理-自定义验证信息源

    1. 简介 我们都知道前台的验证只是为了满足界面的友好性.客户体验性等等.但是如果仅靠前端进行数据合法性校验,是远远不够的.因为非法用户可能会直接从客户端获取到请求地址进行非法请求,所以后台的校验是必 ...

  2. easyui 表单验证validatetype——支持自定义验证

    easyui 的validatebox()提供了自定义验证的方法,为此我把一些常用的数据验证汇总了一下,代码如下: 代码 Code highlighting produced by Actipro C ...

  3. struts2学习(12)struts2验证框架2.自定义验证

    一.例子需求: 对敏感词进行验证: 将struts包中的validators.xml文件拷贝一份到src目录下,在最后面添加自己的验证器: com.cy.validators.SensitiveWor ...

  4. angularJS中的表单验证(包括自定义验证)

    表单验证是angularJS一项重要的功能,能保证我们的web应用不会被恶意或错误的输入破坏.Angular表单验证提供了很多表单验证指令,并且能将html5表单验证功能同他自己的验证指令结合起来使用 ...

  5. Yii CActiveForm 客户端验证(enableClientValidation)和自定义验证

    使用Yii的CActiveForm默认使用服务器端模型(model)的rules规则验证数据. 但这会导致无谓的请求提交,比较好的方式是为了用户体验在客户端也验证,而为了安全性,在服务器端和数据库也做 ...

  6. easyui -validatebox 验证框加载

    问题: easyui验证狂框有时会验证输入字符的位数,或者验证有效字符组合 解决: 使用easyui的验证框,继承验证框,指定输入框为验证框即可 $(function(){ $.extend($.fn ...

  7. Extjs自定义验证介绍

    表单验证实例(空验证,密码确认验证,email验证) 我们可以用单独的js写表单验证,但是extjs已经为我们想到了(自己单独写反而不方便). 在验证之前,我不得不提两个小知识点: //大家在很多的e ...

  8. ASP.NET开发中主要的字符验证方法-JS验证、正则表达式、验证控件、后台验证

    ASP.NET开发中主要的字符验证方法-JS验证.正则表达式.验证控件.后台验证 2012年03月19日 星期一 下午 8:53 在ASP.NET开发中主要的验证方法收藏 <1>使用JS验 ...

  9. 使用自定义验证组件库扩展 Windows 窗体

    使用自定义验证组件库扩展 Windows 窗体             1(共 1)对本文的评价是有帮助 - 评价此主题                          发布日期 : 8/24/20 ...

随机推荐

  1. C#泛型(C#_编程指南)CSDN学习整理笔记

    1.1. 泛型概述 2.0版C#语言和公共语言运行时(CLR)中增加了泛型.泛型将类型参数的概念引入.NETFramework,类型参数使得设计如下类和方法成为可能:这些类和方法将一个或多个类型的指定 ...

  2. RandomAccessFile的使用

    package com.lk.C; import java.io.IOException; import java.io.RandomAccessFile; public class RandomAc ...

  3. 浅析vb.net与vb6的不同

    vb6.0与vb.net 都是微软公司推出的编程工具,而vb.net是在vb6的基础上发展而来的,其语法与VB6.0相似,但VB.net并不是VB6.0 的简单升级,而是增加了更多特性,其中重要的一点 ...

  4. 转: ant condition使用

    评注: 用c语言的方式来,比喻ant...比较好理解 转: http://www.smithfox.com/?e=176 [备忘] Apache Ant中的逻辑判断 [原创链接: http://www ...

  5. Ajax上传文件进度条显示

    要实现进度条的显示,就要知道两个参数,上传的大小和总文件的大小 html5提供了一个上传过程事件,在上传过程中不断触发,然后用已上传的大 小/总大小,计算上传的百分比,然后用这个百分比控制div框的显 ...

  6. JavaScript--DOM事件(笔记)

    第1章 事件流1-1.事件冒泡:事件最开始由最具体的元素(文档中嵌套层次最深的那个节点)接收; 然后逐级向上传播至最不具体的那个节点(文档);1-2.事件捕获:不太具体的节点应该更早接收到事件,而最具 ...

  7. Miniui updateRow更改列字段值

    当UPC等于upccode时,更改列Scanned+1 //先grid.findRow找到UPC等于upccode的行对象 var row = grid.findRow(function (row) ...

  8. JAVA之网页截屏

    先吐槽一下下: 表示接近两个月没有敲代码了,现在看一下代码都感觉有点生了.三天打鱼两天晒网是不行的,再说我本来就有“健忘症”,真的是木有办法啊 ̄へ ̄.我一直信奉一句话:“勤能补拙”,它也是我学习路上的 ...

  9. 【学习笔记】【C语言】变量

    1. 什么是变量 当一个数据的值需要经常改变或者不确定时,就应该用变量来表示.比如游戏积分. 2. 定义变量 1> 目的 任何变量在使用之前,必须先进行定义. 定义变量的目的是:在内存中分配一块 ...

  10. OC6_代理的基本概念

    // // Person.h // OC6_代理的基本概念 // // Created by zhangxueming on 15/6/24. // Copyright (c) 2015年 zhang ...