express-session
阿新 • • 發佈:2018-11-03
express-session 解析
session 是什麼
- (注意這裡說的都是網站相關技術環境下。)
- session 是一種標識對話的技術說法。通過 session ,我們能快速識別使用者的資訊,針對使用者提供不一樣的資訊。
- session 的技術實現上:會對一次對話產生一個唯一的標識進行標識。
session 生命週期
session 標識產生的時機和清除時機:
- 使用者已經登入:這個唯一標識會在使用者登入時產生,使用者點選退出時或者關閉瀏覽器時清除。
- 使用者未登入: 這個唯一標識會在使用者進入網站時產生,使用者關閉所有網站相關頁面時清除。
session 生命週期: 在生成和清除之間,在網站內的頁面任意跳轉,session 標識不會發生變化。從 session 開始到清除,我們叫一次會話,也就是生成 session。
session 特點
- 每次對話, session 的 id 是不一樣的。
- session id 需要每次請求都由客戶端帶過來,用來標識本次會話。這樣就要求客戶端有能用儲存的 sesssionId。
session 技術方案
當前業界通用的方案是:cookie 。當然還有無 cookie 的方案,對每個連結都加上 sessionId 引數。
session 使用流程
- 使用者登入後,將 sessionId 存到 cookie 中。
- 使用者在請求的網站別的服務時,由瀏覽器請求帶上 cookie,傳送到伺服器。
- 伺服器拿到 sessionId 後,通過該 Id 找到儲存到在伺服器的使用者資訊。
- 然後再跟據使用者資訊,進行相應的處理。
從流程有幾個點要關注:
- 什麼時候根據 sessionId 去拿 session
- 確保 session 可用性
結合 express-session 來講講具體 session 的實現。
express-session 的分析
主要關注問題:
- 怎樣產生 session
- 怎樣去拿到 session
- 怎樣去儲存 session
- 怎樣去清除 session
express-session 位置
express-session 有四個部分:
- request, response 與 session 的互動的部分
- session 資料結構
- session 中資料儲存的介面 store
- store 預設實現 memory(cookie 實現已被廢)
不做中間層,直接使用進行處理,只用 express-session 進行處理資料。
const config = global.config;
const session = require('express-session');
/**
* 該中介軟體主要把 express-session 和 client-session 集中起來處理,如果 memcached 出錯了,使用 cookie session
* @param backSession cookeSession 的鍵名
* @returns {function(*=, *=, *)}
*/
module.exports = (backSession) => {
return (req, res, next) => {
let notUseMemcached = _.get(req.app.locals.pc, 'session.removeMemcached', false);
if (req.session && !notUseMemcached) { // memcached 可用
req.memcachedSessionError = false;
} else { // memcached 不可用
// 重建 session
res.emit('sessionError');
req.memcachedSessionError = true;
req.session = new session.Session(req);
req.session.cookie = new session.Cookie({
domain: config.cookieDomain,
httpOnly: false
});
req.session = Object.assign(req.session, req[backSession].sessionBack);
}
Object.defineProperty(req.session, 'reset', {
configurable: true,
enumerable: false,
value: function() {
req.session.destory();
req[backSession].reset();
},
writable: false
});
// 備份資料
req[backSession].sessionBack = req.session;
next();
};
};