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"代码
Jan 09 Javascript
说明你的Javascript技术很烂的五个原因
Apr 26 Javascript
jQuery操作input type=radio的实现代码
Jun 14 Javascript
jQuery手机浏览器中拖拽动作的艰难性分析
Feb 04 Javascript
JavaScript 面向对象与原型
Apr 10 Javascript
JS实现漂亮的淡蓝色滑动门效果代码
Sep 23 Javascript
Node.js实现数据推送
Apr 14 Javascript
浅析jQuery中使用$所引发的问题
May 29 Javascript
JavaScript基于对象方法实现数组去重及排序操作示例
Jul 10 Javascript
iview的table组件自带的过滤器实现
Jul 12 Javascript
JS使用正则表达式提交页面验证的代码
Oct 16 Javascript
JavaScript原型式继承实现方法
Nov 06 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
根德Grundig S400/S500/S700电路分析
2021/03/02 无线电
在“咖啡之国”感受咖啡文化
2021/03/03 咖啡文化
DOTA2游戏同人动画《龙之血》导演接受采访
2021/03/05 欧美动漫
改变Apache端口等配置修改方法
2008/06/05 PHP
PHP 动态随机生成验证码类代码
2010/04/09 PHP
php实现编辑和保存文件的方法
2015/07/20 PHP
php数据访问之增删改查操作
2016/05/09 PHP
php curl获取到json对象并转成数组array的方法
2018/05/31 PHP
用showModalDialog弹出页面后,提交表单总是弹出一个新窗口
2009/07/18 Javascript
javascript 最常用的10个自定义函数[推荐]
2009/12/26 Javascript
重载toString实现JS HashMap分析
2011/03/13 Javascript
js实现目录定位正文示例
2013/11/14 Javascript
jQuery插件扩展测试实例
2016/06/21 Javascript
js学习之----深入理解闭包
2016/11/21 Javascript
MVVM 双向绑定的实现代码
2018/06/21 Javascript
微信小程序MUI侧滑导航菜单示例(Popup弹出式,左侧滑动,右侧不动)
2019/01/23 Javascript
vue自定义指令directive的使用方法
2019/04/07 Javascript
解决nuxt 自定义全局方法,全局属性,全局变量的问题
2020/11/05 Javascript
Java 生成随机字符的示例代码
2021/01/13 Javascript
python装饰器深入学习
2018/04/06 Python
python实现淘宝秒杀脚本
2020/06/23 Python
利用Python对文件夹下图片数据进行批量改名的代码实例
2019/02/21 Python
解决pycharm同一目录下无法import其他文件
2020/02/12 Python
深入了解Python enumerate和zip
2020/07/16 Python
自定义Django_rest_framework_jwt登陆错误返回的解决
2020/10/18 Python
socket.io 和canvas 实现的共享画板功能
2019/05/22 HTML / CSS
火山动力Java笔试题
2014/06/26 面试题
妇产科护士自我鉴定
2013/10/15 职场文书
自我评价200字分享
2013/12/17 职场文书
酒店员工检讨书
2014/02/18 职场文书
学校春季防火方案
2014/06/08 职场文书
服务标语口号
2014/07/01 职场文书
困难补助申请报告
2015/05/19 职场文书
诚信考试主题班会
2015/08/17 职场文书
班级班风口号大全
2015/12/25 职场文书
nginx实现发布静态资源的方法
2021/03/31 Servers