我们公司的大佬 串串,搭建了一套基于koa2的node框架,虽然说是重复造轮子,但适用当前场景的轮子才是最好的,何况很多人还造不出轮子呢~ 大佬搭建的框架命名为 Sponse,其中有很多出色的设计,这里对 session 的设计做个总结(其实是为了自己加深印象,学习大佬的设计)

Sponse意思是海绵,而我们这套框架就如同海绵一样,通过不断吸收其他框架的优秀设计丰满自己

cookie 与 session

做开发的小伙伴对这两个应该在熟悉不过了,这两个一起构建起前后端状态的联系,常见的如维护用户登录状态,用户登录后,需要在服务端记录下该用户的登录状态,前端才可以使用需要登录态的接口,此时,浏览器中的 cookie 就是查询用户是否登录的凭证,在服务端,通常是将用户状态信息存储在缓存中,简单说,就是基于 cookie的session

调用方式

优秀的架构中,调用方式必须是友好的

期望能够通过上下文直接调用,如:获取session对象 ctx.session ; 设置session的值 ctx.session.name = name

逻辑图

整体实现逻辑如下

实现

  1. koa提供了操作cookie的api,开箱即用,官方截图如下

  1. 缓存基于redis实现

详细代码如下:

Session 对象

首先构建一个session对象

核心方法:

  1. save 用于同步cookie
  2. changed 用于检测session对象是否发生修改,为了同步更新缓存中的值
export class Session {private _ctx;isNew: boolean;_json; // session对象的json串,用于比较session对象是否发生变化constructor(ctx, obj) {this._ctx = ctx;if (!obj) this.isNew = true;else {for (const k in obj) {this[k] = obj[k];}}}/*** Save session changes by* performing a Set-Cookie.** @api private*/save() {const ctx = this._ctx;const json = this._json || JSON.stringify(this.inspect());const sid = ctx.sessionId;const opts = ctx.cookieOption;const key = ctx.sessionKey;if (ctx.cookies.get(key) !== sid) {// 设置cookies的值ctx.cookies.set(key, sid, opts);}return json;};/*** JSON representation of the session.** @return {Object}* @api public*/inspect() {const self = this;const obj = {};Object.keys(this).forEach(function (key) {if ('isNew' === key) return;if ('_' === key[0]) return;obj[key] = self[key];});return obj;}/*** Check if the session has changed relative to the `prev`* JSON value from the request.** @param {String} [prev]* @return {Boolean}* @api private*/changed(prev) {if (!prev) return true;this._json = JSON.stringify(this.inspect());return this._json !== prev;};}
复制代码

SessionEngine koa中间件

koa 当然是离不开中间件了,洋葱模型酷炫到不行,非常方便的解决了session对象与缓存的同步

decorator(app) {app.keys = ['signed-key'];const CONFIG = {key: app.config.name + '.sess', /** (string) cookie key (default is koa:sess) */cookie: {// maxAge: 1000, /** (number) maxAge in ms (default is 1 days) */overwrite: false, /** (boolean) can overwrite or not (default true) */httpOnly: true, /** (boolean) httpOnly or not (default true) */signed: true, /** (boolean) signed or not (default true) */}};app.use(async (ctx, next) => {let sess: Session;let sid;let json;ctx.cookieOption = CONFIG.cookie;ctx.sessionKey = CONFIG.key;ctx.sessionId = null;// 获取cookie 对应的值, 即sessionID,就是缓存中的keysid = ctx.cookies.get(CONFIG.key, ctx.cookieOption);// 获取session值if (sid) {try {// 若key存在,则从缓存中获取对应的值json = await app.redisClient.get(sid);} catch (e) {console.log('从缓存中读取session失败: %s\n', e);json = null;}}// 实例化sessionif (json) {// 若缓存中有值,则基于缓存中的值构建session对象ctx.sessionId = sid;try {sess = new Session(ctx, json);} catch (err) {if (!(err instanceof SyntaxError)) throw err;sess = new Session(ctx, null);}} else {sid = ctx.sessionId = sid || Uuid.gen();sess = new Session(ctx, null);}// 为了便于使用,将session挂载到上下文,这样就可以 ctx.session 这么使用了Object.defineProperty(ctx, 'session', {get: function () {return sess;},set: function (val) {if (null === val) return sess = null;if ('object' === typeof val) return sess = new Session(this, val);throw new Error('this.session can only be set as null or an object.');}});try {await next();} catch (err) {throw err;} finally {if (null === sess) {// 设置session=null表示清空sessionctx.cookies.set(CONFIG.key, '', ctx.cookieOption);} else if (sess.changed(json)) {// 检查 session 是否发生变化,若有变化,更新缓存中的值json = sess.save();await app.redisClient.set(sid, json);app.redisClient.ttl(sid);// 设置redis值过期时间为60分钟app.redisClient.expire(sid, 7200);} else {// session 续期app.redisClient.expire(sid, 7200);}}});
复制代码

小结

多多学习~ 点点进步~

原文发布时间:2018年06月29日
作者:小黎也
本文来源掘金如需转载请紧急联系作者

Node工程-构建优秀的Session机制相关推荐

  1. node --- [express] cookie/session 机制与 中间件的使用(路由守卫)

    说明 源代码 记忆.遗忘回顾 使用 cookie/session 机制,让 客户端/服务器 的访问变得有状态 cookie 与 session 由于 HTTP 协议的无状态性,当一次连接断开后. 服务 ...

  2. 怎样对流媒体进行压力测试_对node工程进行压力测试与性能分析「干货」

    作者:小黎 转发链接:https://mp.weixin.qq.com/s/WBe7ZLoqFD9UqNusnv_IDA 前言 在系统上线前,为了看下系统能承受多大的并发和并发下的负载情况,常常会先进 ...

  3. session机制和cookie机制

    一.cookie机制和session机制的区别 具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案.同时我们也看到,由于才服务器端保持状态的方 ...

  4. Kaggle:Home Credit Default Risk 特征工程构建及可视化(2)

    博主在之前的博客 Kaggle:Home Credit Default Risk 数据探索及可视化(1) 中介绍了 Home Credit Default Risk 竞赛中一个优秀 kernel 关于 ...

  5. 转三篇文章关于php中session机制

    解决的问题:同一数据库的两个网站,实现一次登录的功能.网上找了很多关于session的文章,最后参考了下面三篇文章有了解决问题的思路 首先我这边发送要已登录A网站用户的session_id给B网站,然 ...

  6. FLink 优秀的session windows使用案例-Spotify音乐推荐分析

    转载原文:https://blog.csdn.net/lmalds/article/details/69267056 转载作者:malds李麦迪 很棒的文章,博主博文都很好,值得浏览 正文 1.简介 ...

  7. cookie机制和session机制的原理和区别

    文章来源:http://www.javawind.net/5b016f382218328f0122e9d65ae41c9e.jhtml 一.cookie机制和session机制的区别 具体来说cook ...

  8. cookie机制和session机制的原理和区别[转]

    文章来源:http://www.javawind.net/5b016f382218328f0122e9d65ae41c9e.jhtml 一.cookie机制和session机制的区别 具体来说cook ...

  9. 前端系列——Electron工程构建(普通工程,Vue集成)

    前端系列--Electron工程构建(普通工程,Vue集成) Electron 前言 创建Electron工程(npm) 1.创建项目文件夹 2.初始化 3.安装Electron环境 遇到的错误 完成 ...

最新文章

  1. 使用spdevelop进行数据库建模
  2. Jquery基础之DOM操作
  3. matebook14支持触摸屏吗_华为MateBook 14 2021发布,触摸屏成标配
  4. 数据结构源码笔记(C语言):直接选择排序
  5. 教你认清MVC,MVP和MVVM
  6. golang内置数据类型作为函数参数
  7. 归纳推理测试没做完_朋友买了1斤紫菜,2年还没吃完,我教他这样做,2个月就吃完了...
  8. iTween介绍和用法
  9. iOS证书描述文件说明
  10. 微信社群运营是什么,如何做好社群运营?
  11. 女人如何获取安全感?
  12. rufus安装centos8(旧电脑玩Linux)
  13. 遗传算法优化LSTM网络结构(实现自动根据适应度函数:即准确率来全局搜索最佳网络结构):主要被优化参数:网络层数,每层的神经元个数,全连接的层数,全连接层的神经元个数。代码有详细注解
  14. 指数型基金购买技巧汇总(程序猿买基金必备——未完待续)
  15. 什么是用计算机的主存,计算机的主存储器是指什么
  16. 【python】解决给文件写入汉字,中文字符乱码问题
  17. 形象理解二维傅里叶变换
  18. 文章什么时候发布最有利于被搜索引擎收录?
  19. 趁舍友上个厕所的时间,掌握步进电机驱动方式和电路
  20. Facebook的数据公益项目相关工具介绍

热门文章

  1. boost::geometry::model::multi_point用法的测试程序
  2. boost::gregorian模块实现自出生以来的天数的测试程序
  3. ITK:对图像中的结构进行分割
  4. ITK:复制非复合转换NonCompositeTransform
  5. VTK:Utilities之TimeStamp
  6. VTK:PolyData之TransformOrderDemo
  7. VTK:相互作用之InteractorStyleUser
  8. OpenCV VideoCapture与捕获设备,视频文件或图像序列一起使用的实例
  9. OpenGL EnvironmentMapping环境映射的实例
  10. OpenGL Viewport Array视口阵列的实例