Love.Passion.Dream

Node.JS实现用户持久化登陆

上周闲着无事写了一个小应用,晒出来之后被深深的鄙视了一把,应用很简单,但是借此研究了一下用node实现基本的用户账号注册登陆的功能。同时也重温了一下用户持久化登陆与账号加密的问题。鉴于下周就国庆放假了,本月还没有博文输出,所以记录一下,权当笔记。

应用托管到了NAE上面,传送门:爱读书,我用来记录随时闪现在脑海中的书单,也欢迎对这个应用提意见。

要实现可以有注册用户的应用需要解决两个问题:

①用户账号的注册于密码的加密:

这个是用MD5加密就可以了,这样就可以避免类似之前CSDN出现的密码泄露,至于MD5的具体实现那已经是大三的课程了,表示考完试的时候我就已经忘记了,就摘一段百度百科上面的概要说明一下吧:

当用户登录的时候,系统把用户输入的密码进行MD5 Hash运算,然后再去和保存在文件系统中的MD5值进行比较,进而确定输入的密码是否正确。通过这样的步骤,系统在并不知道用户密码的明码的情况下就可以确定用户登录系统的合法性。这可以避免用户的密码被具有系统管理员权限的用户知道。MD5将任意长度的“字节串”映射为一个128bit的大整数,并且是通过该128bit反推原始字符串是困难的,换句话说就是,即使你看到源程序和算法描述,也无法将一个MD5的值变换回原始的字符串,从数学原理上说,是因为原始的字符串有无穷多个,这有点象不存在反函数的数学函数。

MD5的加密可以直接使用node提供的基础模块中的crypto来搞定,实现代码如下:

function md5(str) {
    var md5sum = crypto.createHash('md5');
    md5sum.update(str);
    str = md5sum.digest('hex');
    return str;
}

②账号登陆后的持久化实现:

实现这个必然就是要使用cookie和session了。用户登录验证了用户名和密码之后把用户名和MD5密码做一个可逆的加密作为cookie保存在浏览器中,这个加密不同于MD5的加密,因为它需要在服务器端可逆解密验证用户。同于也可以使用crypto模块中的方法来搞定。

function encrypt(str,secret) {
   var cipher = crypto.createCipher('aes192', secret);
   var enc = cipher.update(str,'utf8','hex');
   enc += cipher.final('hex');
   return enc;
}
function decrypt(str,secret) {
   var decipher = crypto.createDecipher('aes192', secret);
   var dec = decipher.update(str,'hex','utf8');
   dec += decipher.final('utf8');
   return dec;
}

把用上面代码生成的带有用户信息的字符串写入到浏览器中,也就是在header中设置set-cookie或者在node中使用express框架可以直接使用res.cookie

function gen_session(user,res) {
    var auth_token = encrypt(user.username + '\t' + user.password, config.session_secret);
    res.cookie(config.auth_cookie_name, auth_token, {path: '/',maxAge: 1000*60*60*24*7}); //cookie 有效期1周            
}

浏览器端保存cookie之后就是需要再用户每次访问页面的时候做一个检测了:

var cookie = req.cookies[config.auth_cookie_name];
        if(!cookie) return next();

        var auth_token = decrypt(cookie, config.session_secret);
        var auth = auth_token.split('\t');
        var user_name = auth[0];

ok,这样就可以实现一个可以有用户持久化登陆的网站或者应用了。