express-session

express-session 解析

session 是什么

  • (注意这里说的都是网站相关技术环境下。)
  • session 是一种标识对话的技术说法。通过 session ,我们能快速识别用户的信息,针对用户提供不一样的信息。
  • session 的技术实现上:会对一次对话产生一个唯一的标识进行标识。

session 生命周期

session 标识产生的时机和清除时机:

  • 用户已经登录:这个唯一标识会在用户登录时产生,用户点击退出时或者关闭浏览器时清除。
  • 用户未登录: 这个唯一标识会在用户进入网站时产生,用户关闭所有网站相关页面时清除。

session 生命周期: 在生成和清除之间,在网站内的页面任意跳转,session 标识不会发生变化。从 session 开始到清除,我们叫一次会话,也就是生成 session。

session 特点

  • 每次对话, session 的 id 是不一样的。
  • session id 需要每次请求都由客户端带过来,用来标识本次会话。这样就要求客户端有能用保存的 sesssionId。

session 技术方案

当前业界通用的方案是:cookie 。当然还有无 cookie 的方案,对每个链接都加上 sessionId 参数。

session 使用流程

  1. 用户登录后,将 sessionId 存到 cookie 中。
  2. 用户在请求的网站别的服务时,由浏览器请求带上 cookie,发送到服务器。
  3. 服务器拿到 sessionId 后,通过该 Id 找到保存到在服务器的用户信息。
  4. 然后再跟据用户信息,进行相应的处理。

从流程有几个点要关注:

  1. 什么时候根据 sessionId 去拿 session
  2. 确保 session 可用性

结合 express-session 来讲讲具体 session 的实现。

express-session 的分析

主要关注问题:

  • 怎样产生 session
  • 怎样去拿到 session
  • 怎样去保存 session
  • 怎样去清除 session

express-session 位置

  1. express-session位置

express-session 有四个部分:

  1. request, response 与 session 的交互的部分
  2. session 数据结构
  3. session 中数据存储的接口 store
  4. store 默认实现 memory(cookie 实现已被废)
    在这里插入图片描述

不做中间层,直接使用进行处理,只用 express-session 进行处理数据。

const config = global.config;
const session = require('express-session');

/**
 * 该中间件主要把 express-session 和 client-session 集中起来处理,如果 memcached 出错了,使用 cookie session
 * @param backSession cookeSession 的键名
 * @returns {function(*=, *=, *)}
 */
module.exports = (backSession) => {
    return (req, res, next) => {
        let notUseMemcached = _.get(req.app.locals.pc, 'session.removeMemcached', false);

        if (req.session && !notUseMemcached) {  // memcached 可用
            req.memcachedSessionError = false;
        } else {  // memcached 不可用
            // 重建 session
            res.emit('sessionError');
            req.memcachedSessionError = true;
            req.session = new session.Session(req);
            req.session.cookie = new session.Cookie({
                domain: config.cookieDomain,
                httpOnly: false
            });

            req.session = Object.assign(req.session, req[backSession].sessionBack);
        }

        Object.defineProperty(req.session, 'reset', {
            configurable: true,
            enumerable: false,
            value: function() {
                req.session.destory();
                req[backSession].reset();
            },
            writable: false
        });

        // 备份数据
        req[backSession].sessionBack = req.session;

        next();
    };
};

猜你喜欢

转载自blog.csdn.net/qq_33518543/article/details/83026189