nodejs session的原理

nodejs session的原理

Cookie

HTTP协议是没有状态的,但是很多情况下是需要保存一些信息的。比如在用户登录后再次访问网站,没法判断用户是否已经登陆过。因此在这中情况下,我们需要一种数据结构来保存用户信息。于是Cookies就诞生了。

cookies用于在浏览器段保存用户信息。

cookies的特点如下:

  • 保存在客户端浏览器
  • 大小最大为4Kb
  • 如果使用了cookies,访问域名时,浏览器会带上这个域名的cookies

但用户每次向服务器提交信息时都会带上Cookis。Coolies的特性非常不好,比如要访问的是服务器上的静态资源,比如图片,改访问并不需要确认用户,然而浏览器还是会发送Cookis给服务器。

Session

Session的作用和Cookie差不多,但是Session是保存在服务器端的。前面提到用户通过Cookie向服务器提交用户信息,服务器拿到用户信息后该怎么验证呢?查询一下数据库??这样可以实现,但是如果每个用户每次访问都要提交从数据库验证一次,那么将对服务器性能的极大浪费。所以服务器端保存Session用来验证用户身份的合法性。

Session的创建循序

  1. 生成全局唯一标示符
  2. 开辟数据存储空间。一般会在内存中开辟一块空间建立存储Session的数据结构,但是这样会有弊端:系统掉电,那么服务器端的Session将全部丢失。所以一般情况下会将Session保存在数据库或者文件夹中。
  3. 将Session的全局唯一标示符发送给客户端。

现在的问题是服务器怎么将Session的标示符发送给客户端呢。根据HTTP协议,数据的发送可以放在请求行、头域或Body里。

服务器发送给客户端浏览器Session的唯一标示符保存在客户端的Cookies中。

Set-Cookie

服务器返回浏览器的请求中设置Cookie。

{
    "Set-Cookie": "session=r@rdegges.com"
}

服务器会返回一个set-cookie的消息,通知浏览器要设置cookie了,于是浏览器会根据set-cookie里的字段来设置信息了,比如上图的信息就会设置session=r@rdegges.com

实战

现在我们用client-session中间件来配置Session

  1. 安装模块
    var session = require('client-sessions');

  2. 配置session

app.use(session({
    cookieName: 'session',  
    secret: 'random_string_goes_here', //一个随机字符串,因为客户端的数据都是不安全的,所以需要进行加密
    duration: 30*60*1000, //session的过期时间,过期了就必须重新设置
    activeDuration: 5* 60*1000, // 激活时间,比如设置为30分钟,那么只要30分钟内用户有服务器的交互,那么就会被重新激活。
}))

在Session中保存用户信息

app.post('/login',function(req,res){
    User.findOne({email:req.body.email}, function(err,user){ //数据库中查找改用户
        if(!user){ //没有找到
            res.render('login.jade',{error:'用户名或密码错误!'})
        }else{
            if(req.body.password == user.password){
                req.session.user == user //将user信息保存到Session中
                res.redirect('/dashboard')
            }
        }else{
            res.render('login.jade',{error:'用户名或密码错误!'})
        }
    })
})

session层中间件

我们可以会在对每个请求做如下的检查,但是我们完全可以不必这样做。

app.use(function(req, res, next) {
  if (req.session && req.session.user)  {
    User.findOne({ email: req.session.user.email }, function(err, user) {
      if (user) {
        req.user = user;
        delete req.user.password; // delete the password from the session
        req.session.user = user;  //refresh the session value
        res.locals.user = user;
      }
      // finishing processing the middleware and run the route
      next();
    });
  } else {
    next();
  }
});

如果需要是用户登录后才能访问的页面,那么我们可以设计一个检查是否登录的中间函数。

function requireLogin(req,res,next){
    if(!req.user){
        res.redirect('/login')
    }else{
        next();
    }
}

app.get('/dashboard',requireLogion,function(req,res){
    res.render('dashboard.jade)
})

安全性

我们可以在登出时重置Session

app.get('/logout',function(req,res){
    req.session.reset()
    res.redirect('/')
})

总结

Cookie和Session有各自的优缺点

  1. 应用场景

Cookie的典型应用为RememberMe 服务即用户的账户信息通过cookie的形式保存在客户端,当用户再次请求匹配的url时,账户信息会被传送到服务器端,交给相应的程序完成自动登录功能。当然亦可以保存一些客户端信息,如页面布局和搜索历史等。

Session的典型应用场景是用户登录某网站之后,将其登录信息放入session,在以后的每次请求中查询相应的登录信息以确保该用户合法。当然还是有购物车等等经典场景;

  1. 安全性

cookie将信息保存在客户端,如果不进行加密的话,无疑会暴露一些隐私信息,安全性很差,一般情况下敏感信息是经过加密后存储在cookie中,但很容易就会被窃取。而session只会将信息存储在服务端,如果存储在文件或数据库中,也有被窃取的可能,只是可能性比cookie小了太多。

Session安全性方面比较突出的是存在会话劫持的问题,这是一种安全威胁,这在下文会进行更详细的说明。总体来讲,session的安全性要高于cookie;

  1. 性能

Cookie存储在客户端,消耗的是客户端的I/O和内存,而session存储在服务端,消耗的是服务端的资源。但是session对服务器造成的压力比较集中,而cookie很好地分散了资源消耗,就这点来说,cookie是要优于session的;

  1. 时效性

Cookie可以通过设置有效期使其较长时间内存在于客户端,而session一般只有比较短的有效期(用户主动销毁session或关闭浏览器后引发超时);

  1. 其他

Cookie的处理在开发中没有session方便。而且cookie在客户端是有数量和大小的限制的,而session的大小却只以硬件为限制,能存储的数据无疑大了太多。

参考https://segmentfault.com/a/1190000010837077

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值