你真的了解session吗?

172 阅读3分钟

本文已参与『新人创作礼』活动,一起开启掘金创作之路

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第11天,点击查看活动详情

1. 什么是session

  • session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而session保存在服务器上
  • 客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上,这就是session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了

请求过程图,如下所示: image.png

2. session中间件

sessionsession

$ npm install express-session
参数描述
name设置 cookie 中,保存 session 的字段名称,默认为 connect.sid
storesession 的存储方式,默认存放在内存中,也可以使用 redis,mongodb 等
secret通过设置的 secret 字符串,来计算 hash 值并放在 cookie 中,使产生的 signedCookie 防篡改
cookie设置存放 session id 的 cookie 的相关选项,默认为 (default: { path: '/', httpOnly: true, secure: false, maxAge: null })
genid产生一个新的 session_id 时,所使用的函数, 默认使用 uid2 这个 npm 包
rolling每个请求都重新设置一个 cookie,默认为 false
saveUninitialized是指无论有没有session cookie,每次请求都设置个session cookie ,默认给个标示为 connect.sid
resave是指每次请求都重新设置session cookie,假设你的cookie是10分钟过期,每次请求都会再设置10分钟

简单描述下 session:

session 由服务端创建,当一个请求发送到服务端时,服务器会检索该请求里面有没有包含sessionId 标识,如果包含了 sessionId,则代表服务端已经和客户端创建过 session,然后就通过这个 sessionId 去查找真正的 session,如果没找到,则为客户端创建一个新的 session,并生成一个新的 sessionId 与 session 对应,然后在响应的时候将 sessionId 给客户端,通常是存储在 cookie中。如果在请求中找到了真正的 session,验证通过,正常处理该请求。

总之每一个客户端与服务端连接,服务端都会为该客户端创建一个 session,并将 session 的唯一标识 sessionId 通过设置 Set-Cookie 头的方式响应给客户端,客户端将 sessionId 存到 cookie 中。

通常情况下,我们 cookie 和 session 都是结合着来用,当然你也可以单独只使用 cookie 或者单独只使用 session,这里我们就将 cookie 和 session 结合着来用。

3. session实现 #

  1. 在服务器端生成全局唯一标识符session_id
  2. 在服务器内存里开辟此session_id对应的数据存储空间
  3. session_id作为全局唯一标示符通过cookie发送给客户端
  4. 以后客户端再次访问服务器时会把session_id通过请求头中的cookie发送给服务器
  5. 服务器再通过session_id把此标识符在服务器端的数据取出
var express = require('express');
var cookieParser = require('cookie-parser');
var app = express();
app.use(cookieParser());
//存放会话数据 key卡号 value就是卡号对应的数据对象
var sessions = {};
//与客户端约定的会话ID
var SESSION_KEY = 'connect.sid'
//当用户访问根目录的时候 执行对应的回调函数
app.get('/',function(req,res){
    res.setHeader('Content-Type','text/html;charset=utf-8');
   // 1. 先取出cookie中的sessionId 卡号
    var sessionId = req.cookies[SESSION_KEY];
    // 如果有卡号的,也就是有ID的话 老顾客
    if(sessionId){
        //取出此卡号对应的信息,余额
        var sessionObj = sessions[sessionId];
        if(sessionObj){
            //扣掉10块钱
            sessionObj.balance = sessionObj.balance -10;
            res.send('欢迎你老顾客,你卡上还剩'+sessionObj.balance);
        }else{
            genId(res);
        }
    //如果没有的话就是新顾客
    }else{
        genId(res);
    }
    function genId(res){
        //由店家生成一个唯一的卡号
        var id = Date.now()+''+Math.random();
        //要在店家的小本上记录一下此卡号对应的余额
        sessions[id] = {balance:100};
        //把这个卡发给顾客带回家
        res.cookie(SESSION_KEY,id);
        //告诉 用户送他一张卡
        res.send('欢迎你新顾客,送你一张价值100元的剪发卡');
    }
});

app.listen(9090);

文章有错误或者遗漏地方的小伙伴可以在评论区评论哦~