日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

Express-Session:SessionId 機制驅動的一個 Express 會話數據存儲庫

來源: 責編: 時間:2023-12-12 17:01:50 224觀看
導讀Express 是一個 Node.js 的 Web 框架,提供對外服務器的功能。中間件則是 Express 提供的一種擴展能力的插件機制。express-session 就是 Express 的一個中間件。使用 sessionId 的機制,為用戶在網站訪問期間,提供會話數

Express 是一個 Node.js 的 Web 框架,提供對外服務器的功能。中間件則是 Express 提供的一種擴展能力的插件機制。mTW28資訊網——每日最新資訊28at.com

express-session 就是 Express 的一個中間件。使用 sessionId 的機制,為用戶在網站訪問期間,提供會話數據的存儲支持。mTW28資訊網——每日最新資訊28at.com

技術實現上,express-session 就是為每個用戶生成唯一的一個 sessionId(默認通過名為 connect.sid 的 cookie 字段)并存儲在服務器上。在后續請求往返間,后端通過這個 sessionId 就能拿到之前存儲的數據,實現用戶訪問狀態的記憶。mTW28資訊網——每日最新資訊28at.com

注意:會話數據的存儲往往會借助文件系統或者數據庫系統(生產上通常叫緩沖數數據庫,比如 redis)等。express-session 管數據存儲叫 Store,默認使用的是內存(MemoryStore),不過生產上并不推薦。mTW28資訊網——每日最新資訊28at.com

圖片圖片mTW28資訊網——每日最新資訊28at.com

安裝 & 簡單使用

express-session 依賴 express,因此使用時需要保證 express 也存在。mTW28資訊網——每日最新資訊28at.com

$ npm install express express-session

下面是一個簡單的使用。mTW28資訊網——每日最新資訊28at.com

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 個選項的默認值會在未來版本修改,因此官方推薦顯式傳入。mTW28資訊網——每日最新資訊28at.com

express-session 是通過中間件方式注入到 express 應用中的。經 express-session 處理后的請求實例 req 都包含一個 .session 屬性,我們是通過在 .session 屬性上存儲信息,實現前后請求會話數據的保存的。mTW28資訊網——每日最新資訊28at.com

以下,我們將通過 2 個復雜一點的案例來介紹 express-session 的使用。mTW28資訊網——每日最新資訊28at.com

案例介紹

這里舉了 2 個例子,一個是統計用戶頁面訪問次數,還有一個是用戶登錄的例子。mTW28資訊網——每日最新資訊28at.com

統計頁面訪問次數

我們先亮代碼(不是很多)。mTW28資訊網——每日最新資訊28at.com

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 頁面的次數做了統計。mTW28資訊網——每日最新資訊28at.com

  1. 首先express(session({ ... })) 一下,做好會話存儲準備,調用后,會在每一次請求(req)添加一個 .session 對象屬性
  2. 頁面訪問數據存儲在 req.session.views 對象屬性上,初次訪問時是沒有這個對象的,就創建({})
  3. 接下來獲取某個訪問路徑下(req.path)的訪問次數(+1),結束

用戶登錄

用戶登錄是一個稍微復雜一點的例子,分登錄和退出,我們拆開來講。mTW28資訊網——每日最新資訊28at.com

首先,我們針對用戶登錄和未登錄狀態來區別顯示首頁內容:mTW28資訊網——每日最新資訊28at.com

  • 用戶已登錄狀態下,顯示用戶名、暴露退出入口
  • 用戶未登錄狀態下,顯示登錄表單,登錄請求發送至 /login

以下是代碼實現:mTW28資訊網——每日最新資訊28at.com

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 端口的服務器,根據登錄狀態處理首頁展示邏輯。mTW28資訊網——每日最新資訊28at.com

  1. 還是老樣子,首先express(session({ ... })) 一下,做好會話存儲準備,這一步會在每一次請求(req)添加一個 .session 對象屬性
  2. 先跑第一個 / 路徑邏輯,這一步會先經過 isAuthenticated 中間件校驗
  1. 用戶登錄后,我們會創建一個 req.session.user 屬性存儲是用戶數據,isAuthenticated 是檢查這個屬性又沒有的,有  req.session.user 話,就說明登陸了,展示用戶信息(next());沒有  req.session.user 的話,說明未登錄,則忽略用戶信息展示,跳轉至下一個路由處理(next('route'),也就是第 3 步)
  1. 經過上一步,到這一步說明用戶未登錄,我們就發送一個登錄表單,讓用戶填寫。登錄表單包含 user、pass 字段信息。

接下來,我們來看看 /login 頁面的處理邏輯。mTW28資訊網——每日最新資訊28at.com

// ...// 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('/')    })  })})// ...
  1. 為了能正確處理 <form> 表單提交數據,我們使用 express.urlencoded({ extended: false }) 中間件將 form 表單數據收集到 req.body 上
  2. 我們一上來并沒有立即對 req.body.user/req.body.pass 進行校驗,而是調用了 req.session.regenerate() 重新生成用戶會話 sessionId,這能避免會話固定攻擊(session fixation attack)
  3. 接下來,為了做簡單演示,我們沒有校驗密碼,而是直接將提交的用戶名存儲下來(req.session.user = req.body.user)
  4. 在重定向會首頁之前,我們又調用了 req.session.save() 將新 sessionId 下的 user 信息同步給 Store(默認是緩存,實際生產往往是一個緩存數據庫(像 redis))
  5. 最后,重定到首頁,這時候頁面就顯示登錄用戶名了

再來看看退出登錄(/logout)的邏輯。mTW28資訊網——每日最新資訊28at.com

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('/')    })  })})
  1. 首先,我們將 req.session.user 置為空
  2. 然后,req.session.save() 將上面的修改同步到 Store
  3. 接著,通過調用  req.session.regenerate() 重新生成 sessionId,這塊跟登錄一樣,是為了避免會話固定攻擊
  4. 最后,重定到首頁,這時候頁面就未登錄狀態下的登錄框了

總結

express-session 是用來為 express 框架提供會話緩存支持的一個中間件。技術上是通過使用 sessionId 機制提供會話記憶支持的。mTW28資訊網——每日最新資訊28at.com

本文分別列舉了 2 個案例來說明 express-session 的使用:訪問次數和用戶登錄。不過需要注意的是,不管是登錄還是退出,都要有一個新生成 sessionId 的過程(req.session.regenerate()),這是為了避免會話固定攻擊。mTW28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-43315-0.htmlExpress-Session:SessionId 機制驅動的一個 Express 會話數據存儲庫

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: WebStorm 2023.3 來了,更好用,更智能!

下一篇: 前端發起異步請求受瀏覽器同源策略限制,導致跨域問題

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 新巴尔虎左旗| 桃源县| 临高县| 武强县| 沈阳市| 海原县| 通辽市| 鱼台县| 德令哈市| 麻城市| 连平县| 惠来县| 杂多县| 奇台县| 哈密市| 六安市| 赞皇县| 奉节县| 莲花县| 剑川县| 郯城县| 无极县| 阿拉善右旗| 巴马| 鹤山市| 湾仔区| 岱山县| 郧西县| 房产| 榆社县| 德安县| 饶平县| 永城市| 施秉县| 昌黎县| 荔浦县| 河北区| 平顺县| 莎车县| 元阳县| 三穗县|