DoraCMS使用Redis对Session管理的实现
发布在nodejs开发2015年10月22日view:1721前端开发Xmgvzgrkredis
在文章任何区域双击击即可给文章添加【评注】!浮到评注点上可以查看详情。

这两天一直在研究session的问题,session属于开发中老生常谈的问题,但是我却一直搞的很模糊。DoraCMS 使用了最基本的 session来记录登录用户信息,但是并没有对session进行管理(超时控制,清除,存储等)。网上很普遍的一种方式是使用redis,得益于朋友博客的源码,自己也研究了一下,于是把session重新处理了下。

Redis是一个非常适合用于Session管理的数据库。第一,它的结构简单,key-value的形式非常符合SessionID-UserID的存储;第二,读写速度非常快;第三,自身支持数据自动过期和清除;第四,语法、部署非常简单。基于以上原因,很多Session管理都是基于Redis实现的。

Express已经将Session管理的整个实现过程简化到仅仅几行代码的配置的地步了,你完全不用理解整个session产生、存储、返回、过期、再颁发的结构,使用Express和Redis实现Session管理,只要两个中间件就足够了:

express-session

connect-redis

除此之外,redis 也是要装在服务器上的,具体怎么安装参考下这篇文章:

http://www.cnblogs.com/lxx/archive/2013/06/04/3116985.html

DoraCMS 使用redis管理session的方式也比较简单,这里只介绍原理,不列出全部代码:

1、安装必要的中间件 express-session, connect-redis

2、在app.js 中配置redis:

var session = require('express-session');

var RedisStore = require('connect-redis')(session); app.use(session({ secret: Settings.session_secret, store: new RedisStore({ port: Settings.redis_port, host: Settings.redis_host, ttl: 1800 }), resave: true, saveUninitialized: true }));

2、在用户登录成功之后,将cookie记录入缓存中:

// 用户登录提交请求

router.post('/doLogin', function(req, res, next) {
var email = req.body.email;
var password = req.body.password;

var newPsd = DbOpt.encrypt(password,"dora");
User.findOne({email:email,password:newPsd},function(err,user){
    if(user){

// 将cookie存入缓存 filter.gen_session(user, res); console.log('------------登录成功------'); res.end("success"); } else { res.end("error"); } }) });

filter.gen_session 的实现:

function gen_session(user, res) {
var auth_token = user._id + '$$$$'; // 以后可能会存储更多信息,用 $$$$ 来分隔
res.cookie(settings.auth_cookie_name, auth_token,
    {path: '/', maxAge: 1000 * 60 * 60 * 24 * 30, signed: true, httpOnly: true}); //cookie 有效期30天

}

3、 在app.js 中加入检查用户登录状态的方法:

app.use(filter.authUser);

实现:

exports.authUser = function (req, res, next) {

if (req.session.user) {
    req.session.logined = true;
    console.log('--------找到缓存------')
    return next();
} else {
    var auth_token = req.signedCookies[settings.auth_cookie_name];
    console.log('--------找不到session------'+auth_token)
    if (!auth_token) {
        return next();
    }else{
        var auth = auth_token.split('$$$$');
        var user_id = auth[0];

        User.findOne({'_id' : user_id},function(err,user){
            if(err){
                console.log(err)
            }else{
                req.session.user = user;
                req.session.logined = true;
                return next();
            }

        })

    }
}

};

原理大概是这样的,用户登录后,将用户Id记录到cookie中并设置过期时间,在每次请求页面,如果 session 为空,则通过:

var auth_token = req.signedCookies[settings.auth_cookie_name];

4、session 的清理:

router.get('/logout', function(req, res, next) {
req.session.destroy();
res.clearCookie(Settings.auth_cookie_name, { path: '/' });
res.end("success");

});

这种方式来查询是否有用户存储的cookie,如果有,则通过 auth_token 的方式去获取用户Id查询用户信息后存储到session中。因为cookie设置了超时时间,不论浏览器是否关闭或者服务器是否重启,cookie依然是存在的,所以只要没有超时,即使session丢到,通过cookie中存储的key和value值就可以重新找到用户信息并在此存入到session中。我大概是这样理解的,如果有误也请大神补充。

更详细的代码请参考 DoraCMS 源码

评论
发表评论
暂无评论
WRITTEN BY
doramart
前端开发初学者,正在此处奋斗不息
TA的新浪微博
PUBLISHED IN
nodejs开发

nodejs 开发 技术指南

我的收藏