成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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

開發 前端 其他數據庫
express-session 是用來為 express 框架提供會話緩存支持的一個中間件。技術上是通過使用 sessionId 機制提供會話記憶支持的。

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 頁面的次數做了統計。

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

用戶登錄

用戶登錄是一個稍微復雜一點的例子,分登錄和退出,我們拆開來講。

首先,我們針對用戶登錄和未登錄狀態來區別顯示首頁內容:

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

以下是代碼實現:

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 authenticated
function 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 端口的服務器,根據登錄狀態處理首頁展示邏輯。

  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 頁面的處理邏輯。

// ...

// 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)的邏輯。

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 機制提供會話記憶支持的。

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

責任編輯:武曉燕 來源: 寫代碼的寶哥
相關推薦

2020-08-07 10:40:56

Node.jsexpress前端

2024-02-27 08:50:21

格式化Express三方庫

2009-04-21 11:25:10

視頻通訊Express 200LifeSize

2009-06-14 21:59:55

ibmdwWebSphere

2009-09-10 10:19:15

CCIE

2009-12-03 17:54:32

Visual Stud

2010-12-30 11:13:36

卸載SQL Serve

2010-03-24 09:25:01

移動數據中心

2021-08-10 18:36:02

Express原理面試

2011-08-29 14:33:02

Oracle存儲過程

2024-02-06 10:04:49

Express框架repo

2020-03-05 09:54:54

數據驅動數據數據分析

2019-07-15 11:00:24

ReactNode前端

2013-06-14 09:27:51

Express.jsJavaScript

2015-09-10 17:53:32

阿明

2010-12-01 09:09:46

Solaris 11

2020-09-29 07:54:05

Express 飛起

2021-09-26 05:05:46

GoFiber Express

2016-12-15 08:54:52

線程sessionopenSession

2011-07-21 16:28:20

MySQL數據庫帶游標的存儲過程
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品久久久久不卡 | 午夜激情国产 | 成人性视频在线 | 日韩免费网站 | 一色一黄视频 | 成人午夜激情 | 国产精品亚洲片在线播放 | 亚洲视频在线看 | 8x国产精品视频一区二区 | 大学生a级毛片免费视频 | 久久国产精品色av免费观看 | 国产真实精品久久二三区 | 午夜资源 | 精品欧美乱码久久久久久 | 免费成人高清在线视频 | 伊人色综合久久天天五月婷 | 国产日韩一区二区三免费高清 | 国产成人精品一区二区三区在线观看 | 日韩一区二区三区在线观看 | hitomi一区二区三区精品 | 成人深夜小视频 | 久久久久久久久久一区二区 | 自拍偷拍在线视频 | 日韩欧美国产一区二区三区 | 日韩精品999 | 精品久久成人 | 国产精品久久久久久一区二区三区 | 精品国产99 | 久久国产区 | 国产精品国产成人国产三级 | 国产精品视频导航 | 九九九久久国产免费 | 精品视频国产 | 丁香婷婷综合激情五月色 | 成人精品久久日伦片大全免费 | 成年人在线视频 | 在线观看亚洲专区 | 亚洲成人三区 | 亚洲高清三级 | 久久久久久九九九九 | 亚洲福利精品 |