node中的session的具体使用


Posted in Javascript onSeptember 14, 2018

前言

在上一篇中node中的cookie,对cookie进行了相关介绍,本篇将继续前行,对session进行说明。

session是什么

session不就是会话嘛,那什么是会话呢?

会话是一个比连接粒度更大的概念,一次会话可能包含多次连接,每次连接都被认为是会话的一次操作。

当用户在Web页面之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。

当用户请求来自应用程序的 Web 页面时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象。当会话过期或被放弃后,服务器将终止该会话。

说了这么多,我们先来看看这货吧。

node中的session的具体使用

原来session中间件生成的session是一个对象,里面包含了cookie信息。

node中的session

首先,安装express框架,cookieParser中间件,express-session中间件

npm i express --save
npm i cookie-parser --save
npm i express-session --save

默认情况下,Express会话中间件是把session信息存储在内存中,且需要用签名cookie,所以在使cookieParser()时得给它传给一个秘钥。如果没有秘钥,则会提醒 Error: secret option required for sessions

代码如下:

var express = require('express');
var cookieParser = require('cookie-parser');
var session = require('express-session');

var app = express()
app.use(cookieParser())

const hour = 1000 * 60 * 60;
var sessionOpts = {
 // 设置密钥
 secret: 'a cool secret',
 // Forces the session to be saved back to the session store
 resave: true,
 // Forces a session that is "uninitialized" to be saved to the store.
 saveUninitialized: true,
 // 设置会话cookie名, 默认是connect.sid
 key: 'myapp_sid',
 // If secure is set to true, and you access your site over HTTP, the cookie will not be set.
 cookie: { maxAge: hour * 2, secure: false }
}
app.use(session(sessionOpts))

app.use(function(req, res, next) {
 if (req.url === '/favicon.ico') {
  return
 }

 // 同一个浏览器而言,req是同一个
 var sess = req.session;
 console.log(sess)

 if (sess.views) {
  sess.views++;
 } else {
  sess.views = 1;
 }
 res.setHeader('Content-Type', 'text/html');
 res.write('<p>views: ' + sess.views + '</p>');
 res.end();
});

app.listen(4000);

上面代码实现了一个简单的页面浏览计数功能。

运行上面代码,可以打开浏览器,不断刷新页面,观察node程序中打印的sess值。

我们发现,在同一个浏览器中刷新页面,控制台上打印的是同一个session,只不过其中的views的值变了,也就是说,多次http连接对应的是同一个会话。

session存入redis

默认情况下,Express会话中间件是把session信息存储在内存中,但在开发和生产期间,最好有一个持久化的、可扩展的数据存放你的会话数据。express社区已经创建了几个使用数据库的会话存储,包括MongoDB、Redis、Memcached、PostgreSQL以及其他数据库。但低延迟的键/值存储最适合这种易失性数据,这里我们先用redis来存储session信息。

首先,安装connect-redis模块

npm i connect-redis --save

代码如下:

var express = require('express');
var cookieParser = require('cookie-parser');
var session = require('express-session');

var RedisStore = require('connect-redis')(session);

var app = express()
app.use(cookieParser())

var options = {
 host: '127.0.0.1',
 port: 6379,
 db: 1, // Database index to use. Defaults to Redis's default (0).
 prefix: 'ID:' // Key prefix defaulting to "sess:"
 // pass: 'aaa' // Password for Redis authentication
}

const hour = 1000 * 60 * 60;
var sessionOpts = {
 store: new RedisStore(options),
 // 设置密钥
 secret: 'a cool secret',
 // Forces the session to be saved back to the session store
 resave: true,
 // Forces a session that is "uninitialized" to be saved to the store.
 saveUninitialized: true,
 // 设置会话cookie名
 key: 'myapp_sid',
 // If secure is set to true, and you access your site over HTTP, the cookie will not be set.
 cookie: { maxAge: hour * 8, secure: false }
}
app.use(session(sessionOpts)) // 如果没有secret,会提醒 Error: secret option required for sessions

app.use(function(req, res, next) {
 if (req.url === '/favicon.ico') {
  return
 }

 var sess = req.session;
 var id = req.sessionID; // session ID, 只读
 console.log(sess, id);

 if (sess.views) {
  sess.views++; // 如果放在res.end()后,不会自增
  res.setHeader('Content-Type', 'text/html');
  res.write('<p>views: ' + sess.views + '</p>');
  res.write('<p>expires in: ' + (sess.cookie.maxAge / 1000) + 's</p>');
  res.end();
 } else {
  sess.views = 1;
  res.end('welcome to the session demo. refresh!');
 }
});

app.listen(4000);

上面程序中,将会话信息存入了redis的db1数据库中,运行后,刷新浏览器,数据库中的信息如下:

node中的session的具体使用

session存入mongoDb

首先,得安装connect-mongo模块

npm i connect-mongo --save

代码如下:

var express = require('express');
var cookieParser = require('cookie-parser');
var session = require('express-session');

var MongoStore = require('connect-mongo')(session);
const hour = 1000 * 60 * 60

var app = express()
app.use(cookieParser())
app.use(session({
 secret: 'a cool secret',
 key: 'mongo_sid',
 cookie: { maxAge: hour * 8, secure: false },
 resave: true,
 saveUninitialized: true,
 store: new MongoStore({
  url: 'mongodb://@localhost:27017/demodb'
 })
}));

app.use(function(req, res, next) {
 if (req.url === '/favicon.ico') {
  return
 }

 var sess = req.session;
 var id = req.sessionID; // session ID, 只读
 console.log(sess, id);

 if (sess.views) {
  sess.views++;
 } else {
  sess.views = 1;
 }

 res.setHeader('Content-Type', 'text/html');
 res.write('<p>views: ' + sess.views + '</p>');
 res.write('<p>expires in: ' + (sess.cookie.maxAge / 1000) + 's</p>');
 res.write('<p>httpOnly: ' + sess.cookie.httpOnly + '</p>');
 res.write('<p>path: ' + sess.cookie.path + '</p>');
 res.write('<p>secure: ' + sess.cookie.secure + '</p>');
 res.end();
});

app.listen(4000);

运行后,刷新浏览器页面,在demodb数据库中的sessions集合中发现已经存入了如下session信息。

node中的session的具体使用

可能会有人问:结果是看到了,但这过程中到底发生了什么呢?

其实,当浏览器发起第一次请求时,session中间件会生成一个session对象(其中包含cookie信息),这个session对象会存入mongoDb数据库中,同时,请求返回时,浏览器客户端会自动将这个session对象中的cookie保存起来,注意哦,浏览器存的可是cookie,而不是session对象。

这个cookie有一个过期时间,比如,上面代码中设置的是8小时。也就是说,8小时后,这个cookie在浏览器中会自动消失。

最后

现在,你弄清楚session和cookie之间的关系了吗?下一篇我将对node中的密码安全进行介绍,敬请期待哦。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
用 Javascript 验证表单(form)中的单选(radio)值
Sep 08 Javascript
Javascript 面向对象 命名空间
May 13 Javascript
jquery和ajax的关系详细介绍
Nov 29 Javascript
JavaScript操作Cookie详解
Feb 28 Javascript
js日期插件dateHelp获取本月、三个月、今年的日期
Mar 07 Javascript
mpvue跳转页面及注意事项
Aug 03 Javascript
es6中reduce的基本使用方法
Sep 10 Javascript
解决layui页面按钮点击无反应,也不报错的问题
Sep 29 Javascript
layui之数据表格--与后台交互获取数据的方法
Sep 29 Javascript
Vue中el-form标签中的自定义el-select下拉框标签功能
Apr 20 Javascript
微信小程序单选框自定义赋值
May 26 Javascript
微信小程序之导航滑块视图容器功能的实现代码(简单两步)
Jun 19 Javascript
vue3.0 CLI - 2.1 -  component 组件入门教程
Sep 14 #Javascript
vue3.0 CLI - 1 - npm 安装与初始化的入门教程
Sep 14 #Javascript
详解Vue CLI3配置解析之css.extract
Sep 14 #Javascript
vue-cli脚手架build目录下utils.js工具配置文件详解
Sep 14 #Javascript
vue3.0 CLI - 2.6 - 组件的复用入门教程
Sep 14 #Javascript
在vue项目中使用md5加密的方法
Sep 14 #Javascript
在vue项目中引用Iview的方法
Sep 14 #Javascript
You might like
Laravel中注册Facades的步骤详解
2016/03/16 PHP
yii2.0整合阿里云oss的示例代码
2017/09/19 PHP
javascript parseInt 函数分析(转)
2009/03/21 Javascript
JQuery自适应IFrame高度(支持嵌套 兼容IE,ff,safafi,chrome)
2011/03/28 Javascript
基于JQuery实现CheckBox全选全不选
2011/06/27 Javascript
JavaScript高级程序设计(第3版)学习笔记10 再访js对象
2012/10/11 Javascript
多个jquery.datatable共存,checkbox全选异常的快速解决方法
2013/12/10 Javascript
js的Prototype属性解释及常用方法
2014/05/08 Javascript
Spring Boot+AngularJS+BootStrap实现进度条示例代码
2017/03/02 Javascript
jQuery实现可兼容IE6的滚动监听功能
2017/09/20 jQuery
Vue2.0设置全局样式(less/sass和css)
2017/11/18 Javascript
对angularJs中ng-style动态改变样式的实例讲解
2018/09/30 Javascript
[03:08]Ti4观战指南上
2014/07/07 DOTA
跟老齐学Python之类的细节
2014/10/13 Python
python3使用scrapy生成csv文件代码示例
2017/12/28 Python
python调用百度地图WEB服务API获取地点对应坐标值
2019/01/16 Python
PyTorch的深度学习入门教程之构建神经网络
2019/06/27 Python
python简单实现矩阵的乘,加,转置和逆运算示例
2019/07/10 Python
python实现简单成绩录入系统
2019/09/19 Python
Python实现钉钉/企业微信自动打卡的示例代码
2021/02/02 Python
HTML5 Canvas 旋转风车绘制
2017/08/18 HTML / CSS
海淘母婴商城:国际妈咪
2016/07/23 全球购物
京东国际站:JOYBUY
2017/11/23 全球购物
大学生个人实习的自我评价
2014/02/15 职场文书
关于抽烟的检讨书
2014/02/25 职场文书
吃空饷专项治理工作实施方案
2014/03/04 职场文书
企业理念标语
2014/06/09 职场文书
情人节活动总结范文
2015/02/05 职场文书
营业员岗位职责
2015/02/11 职场文书
开天辟地观后感
2015/06/09 职场文书
贫民窟的百万富翁观后感
2015/06/09 职场文书
浪漫的婚礼主持词
2015/06/30 职场文书
教师学习心得体会范文
2016/01/21 职场文书
Python中的min及返回最小值索引的操作
2021/05/10 Python
MySQL面试题讲解之如何设置Hash索引
2021/11/01 MySQL
《进击的巨人》新联动CM 兵长强势出击兽巨人
2022/04/05 日漫