前言上一篇node中的cookie介绍了cookie。本文将继续讲解会话。什么是sessionsession就是session,那么什么是session呢?会话是一个比连接粒度更大的概念。一个会话可能包含多个连接,每个连接都被认为是会话的一个操作。当用户在网页之间跳转时,保存在Session对象中的变量不会丢失,而是在整个用户会话期间一直存在。当用户从应用程序请求网页时,如果用户还没有会话,Web服务器会自动创建一个Session对象。当会话过期或被放弃时,服务器将终止该会话。说了这么多,我们先来看看这款产品。原来session中间件生成的session是一个包含cookie信息的对象。node中的session首先安装express框架,cookieParser中间件,express-session中间件npmiexpress--savenpmicookie-parser--savenpmiexpress-session--saveExpresssession中间件默认保存session的信息存储在内存中并且需要签名的cookie,因此在使用cookieParser()时必须将密钥传递给它。如果没有秘钥,会提示Error:secretoptionrequiredforsessions代码如下:varexpress=require('express');varcookieParser=require('cookie-parser');varsession=require('express-session');varapp=express()app.use(cookieParser())consthour=1000*60*60;varsessionOpts={//设置密钥secret:'acoolsecret',//Forces要保存回会话存储的会话save:true,//强制将“未初始化”的会话保存到存储中。saveUninitialized:true,//设置会话cookie名称,默认为connect.sidkey:'myapp_sid',//如果secure设置为true,并且您通过HTTP访问站点,则不会设置cookie。cookie:{maxAge:hour*2,secure:false}}app.use(session(sessionOpts))app.use(function(req,res,next){if(req.url==='/favicon.ico'){return}//对于同一个浏览器,req是同一个varsess=req.session;console.log(sess)if(sess.views){sess.views++;}else{sess.views=1;}res.setHeader('Content-Type','text/html');水库。write('
views:'+sess.views+'
');res.end();});app.listen(4000);上面的代码实现了一个简单的页面浏览计数功能,运行上面的代码,可以打开浏览器,不断刷新页面,观察node程序中打印的sess值。我们发现在同一个浏览器刷新页面时,控制台打印的是同一个session,但是views的值发生了变化,也就是说多个http连接对应同一个session。会话存储在redis中Express会话中间件默认将会话信息存储在内存中,但是在开发和生产过程中,最好有一个持久化的、可扩展的数据来存储你的会话数据。express社区已经创建了多个使用数据库的会话存储,包括MongoDB、Redis、Memcached、PostgreSQL等。但是低延迟键/值存储最适合这种易失性数据。这里我们先使用redis来存储session信息。首先,安装connect-redis模块npmiconnect-redis--save代码如下:varexpress=require('express');varcookieParser=require('cookie-parser');varsession=require('express-session');varRedisStore=require('connect-redis')(session);varapp=express()app.use(cookieParser())varoptions={host:'127.0.0.1',port:6379,db:1,//要使用的数据库索引。默认为Redis的默认值(0)。prefix:'ID:'//键前缀默认为"sess:"//pass:'aaa'//Redis认证密码}consthour=1000*60*60;varsessionOpts={store:newRedisStore(options),//设置密匙secret:'acoolsecret',//强制将会话保存回会话存储resave:true,//强制将“未初始化”的会话保存到存储。saveUninitialized:true,//设置会话cookie名key:'myapp_sid',//如果安全设置为true,并且您通过HTTP访问您的站点,则不会设置cookie。cookie:{maxAge:hour*8,secure:false}}app.use(session(sessionOpts))//如果没有secret,会提示Error:secretoptionrequiredforsessionsapp.use(function(req,res,next){if(req.url==='/favicon.ico'){return}varsess=req.session;varid=req.sessionID;//sessionID,只读console.log(sess,id);if(sess.views){sess.views++;//如果放在res.end()res.setHeader('Content-Type','text/html');res.write('views:'+sess.views+'
');res.write('expiresin:'+(sess.cookie.maxAge/1000)+'s
');res.end();}else{sess.views=1;res.end('欢迎来到会议demo.refresh!');}});app.listen(4000);上面的程序中,session信息是存放在redis的db1数据库中的。运行后,刷新浏览器,数据库中的信息如下:会话存储在mongoDb中首先,你要安装connect-mongo模块npmiconnect-mongo--save代码如下:varexpress=require('express');varcookieParser=require('cookie-parser');varsession=require('express-session');varMongoStore=require('connect-mongo')(session);consthour=1000*60*60varapp=express()app.use(cookieParser())app.use(session({secret:'acoolsecret',key:'mongo_sid',cookie:{maxAge:hour*8,secure:false},resave:true,saveUninitialized:true,store:newMongoStore({url:'mongodb://@localhost:27017/demodb'})}));app.use(function(req,res,next){if(req.url==='/favicon.ico'){return}varsess=req.session;varid=req.sessionID;//sessionID,只读console.log(sess,id);if(sess.views){sess.views++;}else{sess.views=1;}res.setHeader('Content-Type','text/html');res.write('views:'+sess.views+'
');res.write('expiresin:'+(sess.cookie.maxAge/1000)+'s
');res.write('httpOnly:'+sess.cookie.httpOnly+'
');res.write('path:'+sess.cookie.path+'
');res.write('secure:'+sess.cookie.secure+'
');res.end();});app.listen(4000);运行后,刷新浏览器页面,发现demodb数据库中的session集合中已经存储了如下session可能有人会问:结果是看到了,但是过程中发生了什么?实际上,当浏览器发起第一个请求时,session中间件会生成一个session对象(里面包含cookie信息),这个session对象会存储在mongoDb数据库中。同时,当请求返回时,浏览器客户端会自动保存session对象中的cookie。请注意,浏览器保存的是cookie,而不是会话对象。这个cookie是有过期时间的,比如上面代码中设置了8小时。也就是说,8小时后,这个cookie会自动在浏览器中消失。现在终于搞清楚session和cookie的关系了吗?下一篇我会介绍node中的密码安全,敬请期待。