Node.js编程中客户端Session的使用详解


Posted in Javascript onJune 23, 2015

 静态网站很容易扩展。你只需要全部缓存,不需要考虑从不同服务器组合有状态的内容给用户。

可惜,大多数Web应用使用有状态的内容提供个性化体验。如果你的应用可以登录,就需要记住用户的Session。经典的处理方法是客户端设置包含随机唯一Session标识的Cookie,被标识的Session数据保存到服务端。

扩展有状态服务

当扩展服务的时候,你肯定有三种选择:

  1.     不同服务端同步Session数据
  2.     不同服务端连接单点中心(获取Session)
  3.     保证用户访问同一个服务端

但都有缺陷:

  •     同步数据增加性能开销
  •     单点中心降低系统扩展性
  •     如果用户上次访问的服务端需要维护怎么办

然而,如果你换个角度思考,会发现第四种选择:将Session数据保存在客户端

客户端Session

在客户端保存Session有一些优势:

  •     无所谓哪个服务端,Session数据都有效
  •     不需要维护服务端状态
  •     不需要服务端同步
  •     任意添加新的服务端

但是客户端Session存在一个严重问题:你不能保证用户不篡改Session数据。

比如你在Cookie中保存用户的ID。用户很容易修改它,从而访问别人的账户。

这似乎否定了客户端Session的可能,但有一种方法可以巧妙解决这问题:加密打包Session数据(还是存在Cookie中)。这样就不需要担心用户修改Session数据,服务端会验证数据的。

实际应用上,就是Cookie中保存一个加密的Server Key。Server Key验证后才有权利读取和修改Session数据。这就是客户端Session。

Node客户端Session

Node.JS有一个库可以实现客户端Session:node-client-session.它可以代替Connect(一个Node中间件框架)内置的session和cookieParser中间件。

在Express框架应用中的使用:
 

const clientSessions = require("client-sessions");
app.use(clientSessions({ secret: '0GBlJZ9EKBt2Zbi2flRPvztczCewBxXK' // 设置一个随机长字符串! })

然后,向req.session对象添加属性:
 

app.get('/login', function (req, res){ req.session.username = 'JohnDoe'; });

读取属性:
 

app.get('/', function (req, res){ res.send('Welcome ' + req.session.username); });

使用reset方法终止Session:
 

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

即时注销Persona Session

(注:Persona是Mozzilla推出的网络身份系统)

与服务器端Session不同,客户端Session的问题是服务端无法删除Session。

服务器端架构时,你可以删除Session数据。任意的客户端Cookie标识的Session很可能不存在。但客户端架构时,Session数据不在服务端,不能保证Session数据在每个客户端都被删除。换句话说,我们无法同步用户的客户端状态(已经登录)和服务端状态(注销登录)。
 

为了弥补这个缺陷,客户端Session中添加了过期时间。展开Session数据(被加密打包)前验证过期时间。如果过期了,抛弃Session数据并改变用户状态(如注销登录)。

过期机制在很多应用中运行良好(尤其是短过期时间需求)。如在Persona中,当用户发觉密码收到威胁或已经损坏时,我们需要提供方法让用户立即注销Session数据。

这意味着需要保留一点点状态信息在服务后端。我们处理即时注销的方法是添加一个Token在用户数据表和Session数据中。

每次API调用时比对Session数据中的Token和数据库中的Token。如果不相同,返回错误信息并退出用户。

这样会附加多余的数据库操作去查询Token。幸好,大多数的API调用都需要读取用户数据表,把Token一起带上就好了。

Javascript 相关文章推荐
Javascript 个人笔记(没有整理,很乱)
Jul 07 Javascript
jQuery AJAX回调函数this指向问题
Feb 08 Javascript
JavaScript实现维吉尼亚(Vigenere)密码算法实例
Nov 22 Javascript
javascript实现复选框超过限制即弹出警告框的方法
Feb 25 Javascript
JavaScript使用replace函数替换字符串的方法
Apr 06 Javascript
JavaScript编写简单的计算器
Nov 25 Javascript
Javascript中return的使用与闭包详解
Jan 11 Javascript
JS使用Dijkstra算法求解最短路径
Jan 17 Javascript
Vue基于iview table展示图片实现点击放大
Aug 05 Javascript
vue+element实现动态加载表单
Dec 13 Vue.js
如何管理Vue中的缓存页面
Feb 06 Vue.js
关于对TypeScript泛型参数的默认值理解
Jul 15 Javascript
使用Meteor配合Node.js编写实时聊天应用的范例
Jun 23 #Javascript
使用Node.js为其他程序编写扩展的基本方法
Jun 23 #Javascript
Windows系统下Node.js的简单入门教程
Jun 23 #Javascript
jQuery实现判断滚动条到底部
Jun 23 #Javascript
jQuery实现新消息在网页标题闪烁提示
Jun 23 #Javascript
使用Raygun对Node.js应用进行错误处理的方法
Jun 23 #Javascript
javascript创建函数的20种方式汇总
Jun 23 #Javascript
You might like
PHP实时显示输出
2008/10/02 PHP
php设计模式 Observer(观察者模式)
2011/06/26 PHP
php中计算中文字符串长度、截取中文字符串的函数代码
2011/08/09 PHP
Yii使用CLinkPager分页实例详解
2014/07/23 PHP
Laravel手动分页实现方法详解
2016/10/09 PHP
PHP下载大文件失败并限制下载速度的实例代码
2019/05/10 PHP
ext form 表单提交数据的方法小结
2008/08/08 Javascript
jQuery的强大选择器小结
2009/12/27 Javascript
JS动态创建Table,Tr,Td并赋值的具体实现
2013/07/05 Javascript
使用闭包对setTimeout进行简单封装避免出错
2013/07/10 Javascript
jquery mobile动态添加元素之后不能正确渲染解决方法说明
2014/03/05 Javascript
jQuery插件jFade实现鼠标经过的图片高亮其它变暗
2015/03/14 Javascript
纯js实现无限空间大小的本地存储
2015/06/18 Javascript
jQuery实现可以编辑的表格实例详解【附demo源码下载】
2016/07/09 Javascript
JavaScript实现点击按钮复制指定区域文本(推荐)
2016/11/25 Javascript
@ResponseBody 和 @RequestBody 注解的区别
2017/03/08 Javascript
Vue源码学习之初始化模块init.js解析
2017/11/02 Javascript
Nodejs下使用gm圆形裁剪并合成图片的示例
2018/02/22 NodeJs
新手必须知的Node.js 4个JavaScript基本概念
2018/09/16 Javascript
详解Vue.js v-for不支持IE9的解决方法
2018/12/29 Javascript
基于vue-cli、elementUI的Vue超简单入门小例子(推荐)
2019/04/17 Javascript
vue+element加入签名效果(移动端可用)
2019/06/17 Javascript
在JavaScript中实现链式调用的实现
2019/12/24 Javascript
JavaScript实现公告栏上下滚动效果
2020/03/13 Javascript
JavaScript检测浏览器是否支持CSS变量代码实例
2020/04/03 Javascript
解决vue页面渲染但dom没渲染的操作
2020/07/27 Javascript
浅谈Vue开发人员的7个最好的VSCode扩展
2021/01/20 Vue.js
[01:52]PWL S2开团时刻第四期——DOTA2成语故事
2020/12/03 DOTA
linux系统使用python获取内存使用信息脚本分享
2014/01/15 Python
利用python实现汉字转拼音的2种方法
2019/08/12 Python
pyenv与virtualenv安装实现python多版本多项目管理
2019/08/17 Python
详解使用django-mama-cas快速搭建CAS服务的实现
2019/10/30 Python
Wedgwood美国官网:英国骨瓷,精美礼品及家居装饰
2018/02/17 全球购物
医药代表个人求职信范本
2013/12/19 职场文书
反腐倡廉警示教育活动总结
2014/05/05 职场文书
2015暑期爱心支教策划书
2015/07/14 职场文书