管理后台的登录功能-重新思考

每个网站、APP都几乎必然有其管理后台,其中管理的内容则是公司的核心技术财产。而登录模块则是这扇大门,其安全的重要性可想而知。我们知道,功能越多,安全性就会越低,所以我们有必要重新审视一下,管理后台的登录界面到底需要些什么功能。

一、功能模块的取舍

1、基本的账号密码登录。这个无可避免是必然需要的了。

2、图片验证码。验证码的目的是为了阻止机器人暴力撞库,作为管理后台很有必要,而且是要每次登录请求都需重新验证。

3、填完用户名或密码时,Ajax实时验证。这个功能常见于一些自动管理后台的注册模块,用于验证用户名是否已被占用。但此功能通常会导致不需经过验证码验证,从而使得暴力撞库有机可乘。

4、记住我选项。这是一个使用cookie记住登录用户的功能,使用户下次再来时可以不需要再登录即可通过验证。但cookie必然需要记录 用户ID或用户名 相关的信息,存在浏览器中,有一定的CSRF攻击风险和信息泄漏风险。

5、找回密码功能。这是一个高危功能,无论是逻辑疏漏还是安全不严谨,都会导致账号的失窃。参考1月份支付宝找回密码的危机。所以建议做法是,公司文档保存相关的账号密码信息,如遇实在无法登录,则找技术人员进入数据库修改密码(加密后)。

6、注册功能。这个不要做在外面,在后台的功能里加一个添加用户会安全很多。

7、第三方登录。如QQ登录、微信登录?不需要,大家都知道QQ很容易被盗号,不宜作为安全性要求高的系统的登录入口。微信则需要拿手机出来扫码,不如直接输入密码来得方便,另外它还需要申请微信公众号以及500块每年的公众号认证费用。

综上,得出一个够用、安全的管理后台的登录界面

二、安全功能

1、验证码安全。以AJAX提交为例,每次尝试登录后,无论是否登录成功,后端都要注销当前验证码SESSION,前端JS刷新验证码。后台要注销SESSION是以免黑客屏蔽JS导致验证码只需一写次,从而导致爆库。

2、网络传输安全。最好使用https加密,以免网络传输过程泄露账号密码,如在咖啡店等他人WIFI环境。如果没有使用HTTPS,则应该在前端JS加密登录名和密码,后端再解密。因为JS是明文的,所以要使用非对称性加密(如RSA),JS使用公钥加密,服务端使用私钥解密。甚至对JS文件本身也可以作一些加密压缩。为什么登录名也要加密呢?还是避免信息泄露,以免别人根据登录名猜出密码。

3、登录成功时重新生成SESSION_ID。主要是为了防止固定会话ID的CSRF攻击

三、登录日志

知己知彼,战斗才能胜利。上面这些功能和安全,都是一些通用的防守攻击套路。但敌人在暗我在明,敌人什么时候派出过特务,什么时候发出过攻击,发起了什么样的攻击?仅通过上面的功能,我们无从得知。所以,我们还需要一个监控器--登录日志。

然后这个登录日志,我们需要记录些什么东西呢? 登录名、是否成功、IP地址、时间。但是,这还不够,这样我们只能分析到了是谁有攻击我们,但是分析不到他是通过什么方式来攻击。那还要记录什么呢?URL地址(含GET数据)、POST数据。但需要注意的是,我们登录时的密码也在POST数据里,切不可将密码存储在登录日志里,即使是RSA加密过的也不行,应以***星号代替,否则这和明文存储密码没什么差别。

四、前端代码

前端代码的要点是登录时RSA加密账号密码,使用的是 jsencrypt.js 库,Ajax提交表单用的是 jquery.form.js 。核心代码如下,需要注意的是,ajaxForm接受的这两个回调函数,参数名是固定的无法修改,修改表单数据用的是formData,提交成功回调的结果名是responseText。标紫色的两个变量是后台输出的模板变量。

//AJAX提交登录表单
$(function(){
    var formSubOpt = {
        beforeSubmit: encodeForm,
        success: formRes
    };
    $("#loginform").ajaxForm( formSubOpt );
});
//提交成功
function formRes(responseText){    //参数名要为这个
//    console.log(responseText);
    ajaxAlerts(responseText);    //提示
    if(responseText.code<0){
        changeVer();
        $("input[name=ver]").val("");
    }
    if(responseText && responseText.code==0){
        setTimeout(function(){
            location.href = "{$toURL}";
        },750);
    }
}

//RSA加密账号密码
var RSApubKey = "{$RSApubKey}";
//console.log(RSApubKey);
function encodeForm(formData){
//    console.log(formData);    //这是要提交的参数
    var crypt = new JSEncrypt();
    crypt.setKey( RSApubKey );
    var USER = crypt.encrypt( $("input[name=name]").val() );
    var PW = crypt.encrypt( $("input[name=psw]").val() );
//    console.log( PW );
    formData[0].value = USER;
    formData[1].value = PW;
}

五、后端代码

略。按前面的分析思路来写即可

posted @ 2017-08-03 10:22  wuruhua  阅读(265)  评论(0编辑  收藏  举报