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 相关文章推荐
jQuery textarea的长度进行验证
May 06 Javascript
子窗口、父窗口和Silverlight之间的相互调用
Aug 16 Javascript
jquery 与NVelocity 产生冲突的解决方法
Jun 13 Javascript
jQuery图片的展开和收缩实现代码
Apr 16 Javascript
javascript制作的网页侧边弹出框思路及实现代码
May 21 Javascript
Summernote实现图片上传功能的简单方法
Jul 11 Javascript
JS实现向iframe中表单传值的方法
Mar 24 Javascript
Vue 2.0中生命周期与钩子函数的一些理解
May 09 Javascript
vue2.0 路由不显示router-view的解决方法
Mar 06 Javascript
JavaScript实现图片懒加载的方法分析
Jul 05 Javascript
原生javascript实现连连看游戏
Jan 03 Javascript
vue移动端实现手机左右滑动入场动画
Jun 17 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 set_time_limit(0) 设置程序执行时间的函数
2010/05/26 PHP
web站点获取用户IP的安全方法 HTTP_X_FORWARDED_FOR检验
2013/06/01 PHP
Fatal error: session_start(): Failed to initialize storage module: files问题解决方法
2014/05/04 PHP
php实现文本数据导入SQL SERVER
2015/05/17 PHP
PHP 5.6.11中CURL模块问题的解决方法
2016/08/08 PHP
php 自定义错误日志实例详解
2016/11/12 PHP
PHP实现判断数组是一维、二维或几维的方法
2017/02/06 PHP
laravel 框架实现无限级分类的方法示例
2019/10/31 PHP
jQuery中对节点进行操作的相关介绍
2013/04/16 Javascript
JQuery控制radio选中和不选中方法总结
2015/04/15 Javascript
JavaScript操作Cookie方法实例分析
2015/05/27 Javascript
JavaScript中数据结构与算法(三):链表
2015/06/19 Javascript
javascript+css3 实现动态按钮菜单特效
2016/02/06 Javascript
jQuery获取file控件中图片的宽高与大小
2016/08/04 Javascript
使用Node.js搭建静态资源服务详细教程
2017/08/02 Javascript
从零开始在NPM上发布一个Vue组件的方法步骤
2018/12/20 Javascript
微信小程序时间标签和时间范围的联动效果
2019/02/15 Javascript
微信小程序基于高德地图查找位置并显示文字
2019/10/30 Javascript
jQuery带控制按钮轮播图插件
2020/07/31 jQuery
[39:46]完美世界DOTA2联赛PWL S2 LBZS vs Rebirth 第二场 11.25
2020/11/25 DOTA
python中使用正则表达式的后向搜索肯定模式(推荐)
2017/11/11 Python
python+selenium实现京东自动登录及秒杀功能
2017/11/18 Python
python导出chrome书签到markdown文件的实例代码
2017/12/27 Python
Python使用Pickle模块进行数据保存和读取的讲解
2019/04/09 Python
Python Gitlab Api 使用方法
2019/08/28 Python
python 通过手机号识别出对应的微信性别(实例代码)
2019/12/22 Python
python闭包、深浅拷贝、垃圾回收、with语句知识点汇总
2020/03/11 Python
利用Python制作动态排名图的实现代码
2020/04/09 Python
浅谈HTML5 服务器推送事件(Server-sent Events)
2017/08/01 HTML / CSS
Petmate品牌官方网站:宠物用品
2018/11/25 全球购物
美国家用和厨房电器销售网站:Appliances Connection
2020/01/24 全球购物
毕业生求职的求职信
2013/12/05 职场文书
动漫专业高职生职业生涯规划书
2014/02/15 职场文书
中秋节祝酒词
2015/08/12 职场文书
react合成事件与原生事件的相关理解
2021/05/13 Javascript
解决SpringBoot文件上传临时目录找不到的问题
2021/07/01 Java/Android