Express 是一个 Node.js 的 Web 框架,提供对外服务器的功能。中间件则是 Express 提供的一种扩展能力的插件机制。
express-session 就是 Express 的一个中间件。使用 sessionId 的机制,为用户在网站访问期间,提供会话数据的存储支持。
技术实现上,express-session 就是为每个用户生成唯一的一个 sessionId(默认通过名为 connect.sid 的 cookie 字段)并存储在服务器上。在后续请求往返间,后端通过这个 sessionId 就能拿到之前存储的数据,实现用户访问状态的记忆。
注意:会话数据的存储往往会借助文件系统或者数据库系统(生产上通常叫缓冲数数据库,比如 redis)等。express-session 管数据存储叫 Store,默认使用的是内存(MemoryStore),不过生产上并不推荐。
图片
express-session 依赖 express,因此使用时需要保证 express 也存在。
$ npm install express express-session
下面是一个简单的使用。
var express = require('express')var session = require('express-session')var app = express()app.use(session({ secret: 'keyboard cat', resave: false, saveUninitialized: true}))
secret 是必填项,作为生成 sessio ID 的盐值。resave、saveUninitialized 都是选填项,不过由于这 2 个选项的默认值会在未来版本修改,因此官方推荐显式传入。
express-session 是通过中间件方式注入到 express 应用中的。经 express-session 处理后的请求实例 req 都包含一个 .session 属性,我们是通过在 .session 属性上存储信息,实现前后请求会话数据的保存的。
以下,我们将通过 2 个复杂一点的案例来介绍 express-session 的使用。
这里举了 2 个例子,一个是统计用户页面访问次数,还有一个是用户登录的例子。
我们先亮代码(不是很多)。
var express = require('express')var session = require('express-session')var app = express()// 1)app.use(session({ secret: 'keyboard cat', resave: false, saveUninitialized: true}))app.use(function (req, res, next) { // 2) if (!req.session.views) { req.session.views = {} } // get the url pathname var pathname = req.path // 3) // count the views req.session.views[pathname] = (req.session.views[pathname] || 0) + 1 next()})app.get('/foo', function (req, res, next) { res.send('you viewed this page ' + req.session.views['/foo'] + ' times')})app.get('/bar', function (req, res, next) { res.send('you viewed this page ' + req.session.views['/bar'] + ' times')})app.listen(3000)
这里我们起了一个监听在 3000 端口的服务器,对访问 /foo、/bar 页面的次数做了统计。
用户登录是一个稍微复杂一点的例子,分登录和退出,我们拆开来讲。
首先,我们针对用户登录和未登录状态来区别显示首页内容:
以下是代码实现:
var escapeHtml = require('escape-html')var express = require('express')var session = require('express-session')var app = express()// 1)app.use(session({ secret: 'keyboard cat', resave: false, saveUninitialized: true}))// 2.1) middleware to test if authenticatedfunction isAuthenticated (req, res, next) { if (req.session.user) next() else next('route')}// 2)app.get('/', isAuthenticated, function (req, res) { // this is only called when there is an authentication user due to isAuthenticated res.send('hello, ' + escapeHtml(req.session.user) + '!' + ' <a href="/logout">Logout</a>')})// 3)app.get('/', function (req, res) { res.send('<form actinotallow="/login" method="post">' + 'Username: <input name="user"><br>' + 'Password: <input name="pass" type="password"><br>' + '<input type="submit" text="Login"></form>')})// ...app.listen(3000)
这里我们起了一个监听在 3000 端口的服务器,根据登录状态处理首页展示逻辑。
接下来,我们来看看 /login 页面的处理逻辑。
// ...// 1)app.post('/login', express.urlencoded({ extended: false }), function (req, res) { // login logic to validate req.body.user and req.body.pass // would be implemented here. for this example any combo works // regenerate the session, which is good practice to help // guard against forms of session fixation // 1) req.session.regenerate(function (err) { if (err) next(err) // store user information in session, typically a user id // 2) req.session.user = req.body.user // save the session before redirection to ensure page // load does not happen before session is saved // 3) req.session.save(function (err) { if (err) return next(err) // 4) res.redirect('/') }) })})// ...
再来看看退出登录(/logout)的逻辑。
app.get('/logout', function (req, res, next) { // logout logic // clear the user from the session object and save. // this will ensure that re-using the old sessionId // does not have a logged in user // 1) req.session.user = null // 2) req.session.save(function (err) { if (err) next(err) // regenerate the session, which is good practice to help // guard against forms of session fixation // 3) req.session.regenerate(function (err) { if (err) next(err) // 4) res.redirect('/') }) })})
express-session 是用来为 express 框架提供会话缓存支持的一个中间件。技术上是通过使用 sessionId 机制提供会话记忆支持的。
本文分别列举了 2 个案例来说明 express-session 的使用:访问次数和用户登录。不过需要注意的是,不管是登录还是退出,都要有一个新生成 sessionId 的过程(req.session.regenerate()),这是为了避免会话固定攻击。
本文链接:http://www.28at.com/showinfo-26-43315-0.htmlExpress-Session:SessionId 机制驱动的一个 Express 会话数据存储库
声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com