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.www897cc.com/showinfo-26-43315-0.htmlExpress-Session:SessionId 機制驅動的一個 Express 會話數據存儲庫
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com