app.use(session({
name: config.session.name,
secret: config.session.secret,
resave: true,
saveUninitialized: false,
cookie: config.session.cookie,
store: new MongoStore({
url: config.url
})
}))
express-session是一個中間件,接收一寫參數,返回一個函數:
return function session(req, res, next) {}
首先當請求到達服務端的時候,解析request,拿到cookie中的sessionId,保存到req上供后面使用
var cookieId = req.sessionID = getcookie(req, name, secrets);
如果請求的cookie中沒有sessionID,會由一個generate方法創建一個session對象,同時在request對象上添加了sessionID,session
store.generate = function (req) {
req.sessionID = generateId(req);
req.session = new Session(req);
req.session.cookie = new Cookie(cookieOptions);
if (cookieOptions.secure === 'auto') {
req.session.cookie.secure = issecure(req, trustProxy);
}
};
只要修改了session比如req.session.view++
,express-session通過重寫了response.end
,在返回數據的時候進行一次保存:
var _end = res.end;
res.end = function end(chunk, encoding) {
....
return _end.call(res, chunk, encoding);
}
那么如果沒有修改session,是否保存到數據庫或者內存中,由函數shouldSave來處理:
function shouldSave(req) {
// cannot set cookie without a session ID
if (typeof req.sessionID !== 'string') {
debug('session ignored because of bogus req.sessionID %o', req.sessionID);
return false;
}
return !saveUninitializedSession && cookieId !== req.sessionID
? isModified(req.session)
: !isSaved(req.session)
}
function isSaved(sess) {
return originalId === sess.id && savedHash === hash(sess);
}
function isModified(sess) {
return originalId !== sess.id || originalHash !== hash(sess);
}
其中涉及到saveUninitialized和resave的配置,
saveUninitialized : 是否強制將未初始化的 session 存儲。當新建了一個 session 且未設定屬性或值時,它就處於未初始化狀態。
resave:是指每次請求都重新設置session cookie,最直觀的表現就是客戶端的cookie的有效期在變化;
下面是整理的不同配置下在是否有sessionId的cookie的情況下的處理結果表格:
saveUninitialized | resave | 是否向服務端傳遞了sessionId的cookie | 對應的處理 |
---|---|---|---|
true | true/false | 否 | 1.由isSaved來決定結果,而此時 isSaved為false shouldSave為true 2.執行保存session的操作 |
true | true/false | 是 | 1.由isSaved來決定結果,而此時isSaved為true, shouldSave為false 2.不執行保存session的操作 |
false | true/false | 否 | 1.cookieId為undefined 和req.sessionID不相等 2.由isModified來決定結果,而此時isModified為false shouldSave為false 3.這種情況說的就是如果session未初始化不存儲起來,可以減輕服務端的壓力 |
false | false | 是 | 1.cookieId 與 req.sessionID一致 2.有isSaved來決定,此時isSaved()為true,shouldSave為false 3.不執行保存session的操作 |
false | true | 是 | 1.cookieId 與 req.sessionID一致 2.有isSaved來決定,此時isSaved()為false,shouldSave為true 3.執行保存session的操作 |
demo地址:
https://github.com/blank-x/node-daily/tree/master/express-session_