express express-session的使用小結(jié)
簡(jiǎn)介
express-session是express中的一個(gè)處理session的中間件,可以說是express中最常見的中間件之一了.
由于會(huì)話管理依賴cookie的使用,所以它的api中有很多用于控制cookie的部分.
總的來說express-session有如下的特點(diǎn):
- session管理(基本功能)
- cookie簽名
- 可替換持久儲(chǔ)存模塊
本文中使用的版本為1.15.6.
安裝
npm install express-session --save
引入&使用
const express = require('express');
const app = new express();
const expressSession = require('express-session');
// 使用express-session
app.use(expressSession({
secret:'hello world',// cookie簽名 這個(gè)屬性是必須的 具體配置和`cookie-parser`一樣
saveUninitialized:true, // 是否自動(dòng)初始化 默認(rèn)為true
resave:false,// 當(dāng)用戶session無變化的時(shí)候依然自動(dòng)保存
cookie:{ // cookie的信息具體操作和`cookie-parser`一樣
maxAge:1800000// 30分鐘后過期
},
rolling:true// 每次請(qǐng)求的時(shí)候覆寫cookie
}))
會(huì)話簡(jiǎn)介
在express-session文檔中有如下的一句說明:
Note Session data is not saved in the cookie itself, just the session ID. Session data is stored server-side.
Session中包含的數(shù)據(jù)不會(huì)保存在cookie中,僅僅是在cookie中保存了一個(gè)SessionId而已.實(shí)際的session的數(shù)據(jù)保存在服務(wù)端.
簡(jiǎn)單理解就是一個(gè)Map,鍵對(duì)應(yīng)的是session id值保存在cookie中,值對(duì)應(yīng)的是用戶保存在服務(wù)端的數(shù)據(jù).
api介紹
參數(shù)
創(chuàng)建express-cookie參數(shù)基本分為兩種.
- 針對(duì)于cookie的設(shè)置
- 針對(duì)于express-session的設(shè)置
cookie設(shè)置一覽:
app.use(expressSession({
secret:'hello world', // cookie 簽名必須有否則會(huì)報(bào)錯(cuò)
cookie:{
domain:<參數(shù)>,
expires:<參數(shù)>,
httpOnly:<參數(shù)>,
path:<參數(shù)>,
sameSite:<參數(shù)>,
secure:<參數(shù)>,
maxAge:1800000
}
}));
而這些對(duì)應(yīng)的參數(shù)就是服務(wù)端對(duì)于cookie的寫入?yún)?shù),至于各個(gè)參數(shù)是什么意思參考下面的文章:
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Set-Cookie
express-session部分設(shè)置:
app.use(expressSession({
secret:'hello world', // cookie 簽名必須有否則會(huì)報(bào)錯(cuò)
genid:function (request) { // 用于替換掉默認(rèn)ID生成的函數(shù) 第一個(gè)參數(shù)為reqeust
return '隨機(jī)id'
},
name:'connect.sid',// 每次響應(yīng)中向cookie中起始的內(nèi)容,默認(rèn)起始為`connect.sid`,
proxy:true,// 對(duì)于cookie使用secure后,在傳遞的過程中相信反向代理服務(wù)器,默認(rèn)為undefined只相信正向代理
resave:true,// 在一次會(huì)話中無論是否session被改變都會(huì)進(jìn)行強(qiáng)制的儲(chǔ)存
rolling:true,// 在每次會(huì)話中的響應(yīng)中都覆寫一次cookie,重置倒計(jì)時(shí)
saveUninitialized:true,// 將一個(gè)新創(chuàng)建還未修改的會(huì)話進(jìn)行儲(chǔ)存,默認(rèn)為true
store:object// 一個(gè)儲(chǔ)存對(duì)象,默認(rèn)使用的是`MemoryStore`這個(gè)存儲(chǔ)器
unset:'keep'// 控制沒有設(shè)置`req.session`時(shí)候的行為(使用delete刪除或者賦值null),默認(rèn)'keep'會(huì)話期間不會(huì)保留,'destroy'會(huì)話完成后刪除.
}));
方法
在request.session上掛載的session對(duì)象,除了有你添加的內(nèi)容外,還有默認(rèn)的方法存在:
req.session.regenerate(function(err) {
// 調(diào)用這個(gè)方法從新生成一個(gè)新的會(huì)話,完成后觸發(fā)
})
req.session.destroy(function(err) {
// 刪除這個(gè)會(huì)話,完成后觸發(fā)
})
req.session.reload(function(err) {
// 從新加載session數(shù)據(jù),完成后觸發(fā)回調(diào)
})
req.session.save(function(err) {
// 使用當(dāng)前內(nèi)存中的數(shù)據(jù)保存到儲(chǔ)存器中
// 默認(rèn)在會(huì)話結(jié)束的時(shí)候就會(huì)自動(dòng)調(diào)用這個(gè)方法
})
req.session.touch() // 更新cookie中的maxAge,一般不需要手動(dòng)操作,交由中間件
屬性
同樣的在session實(shí)例上也有很多屬性:
req.session.id // 保存唯一的會(huì)話id值,不可修改 req.session.cookie // 以鍵值對(duì)的形式保存cookie的原始數(shù)據(jù) req.session.cookie.maxAge // 以毫秒的形式返回剩余存活時(shí)間 req.sessionID // 保存唯一的會(huì)話id,只讀
一個(gè)簡(jiǎn)單的例子
一個(gè)簡(jiǎn)單的登錄例子:
const express = require('express');
const app = new express();
const expressSession = require('express-session');
const userDb = new Map();
app.use(expressSession({
secret:'hello world',
saveUninitialized:true,
resave:false,
cookie:{
maxAge:1800000
},
rolling:true,
}));
app.get('/login', (request, response) => {
const
id = request.query.id,
pwd = request.query.pwd;
if(id && pwd){
if(userDb.has(id+pwd)){
response.send('該用戶已登錄');
}else{
request.session.userId = id+pwd;
userDb.set(id+pwd,id);
response.redirect('/');
}
}else{
response.send('請(qǐng)輸入正確的帳號(hào)和密碼');
}
});
app.get('/logout',(request, response)=>{
const userId = request.session.userId;
request.session.destroy((err)=>{
if(err || !userDb.has(userId)){
response.send('登出失敗');
}else{
userDb.delete(userId);
response.send('登出成功');
}
});
});
app.get('/',(request, response)=>{
if(request.session.userId && userDb.has(request.session.userId)){
response.send(`歡迎回來${userDb.get(request.session.userId)}`);
}else{
response.send('還未登錄');
}
});
app.use((request, response) => {
response.send('404 not found');
});
app.listen(8888, '127.0.0.1');
在瀏覽器中依次輸入以下url來模擬登錄行為:
localhost:8888/ localhost:8888/login?id=ASCll&pwd=123456 localhost:8888/ localhost:8888/logout localhost:8888/
暗坑
我在chrome瀏覽器下運(yùn)行上面的例子多次后發(fā)現(xiàn)一個(gè)問題,瀏覽器會(huì)進(jìn)行預(yù)讀取網(wǎng)頁來提高性能,也就是說在瀏覽器中當(dāng)我url輸入到如下的地方時(shí):
localhost:8888/logo
根據(jù)我之間多次進(jìn)入這個(gè)頁面瀏覽器會(huì)提前訪問這個(gè)頁面localhost:8888/logout,而導(dǎo)致服務(wù)器直接刪除session等到真正進(jìn)入到頁面的時(shí)候已經(jīng)是第二次加載頁面了,導(dǎo)致每次登出都顯示失敗.
希望有經(jīng)驗(yàn)的朋友能給出一個(gè)合理的解決方案.
注意
當(dāng)express-session和cookie-parser一起使用的時(shí)候?qū)τ?code>cookie的簽名必須一致.
express-session的存儲(chǔ)實(shí)例是可以更換的,默認(rèn)使用MemoryStore只適合于測(cè)試和開發(fā)使用,生產(chǎn)環(huán)境必須要使用其他的儲(chǔ)存實(shí)例,否則會(huì)出現(xiàn)內(nèi)存碎片問題,在官方文檔中給出了已經(jīng)實(shí)現(xiàn)的接口,可以對(duì)接redis以及mongodb等數(shù)據(jù)庫.
該列表在官方文檔的最后:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- express+vue+mongodb+session 實(shí)現(xiàn)注冊(cè)登錄功能
- express如何使用session與cookie的方法
- nodejs使用express獲取get和post傳值及session驗(yàn)證的方法
- Express + Session 實(shí)現(xiàn)登錄驗(yàn)證功能
- node.js中express-session配置項(xiàng)詳解
- node.js 中間件express-session使用詳解
- 詳解Node.js開發(fā)中的express-session
- 詳解node.js平臺(tái)下Express的session與cookie模塊包的配置
- 詳解nodejs express下使用redis管理session
- Nodejs進(jìn)階:express+session實(shí)現(xiàn)簡(jiǎn)易登錄身份認(rèn)證
相關(guān)文章
使用Node.js實(shí)現(xiàn)Clean?Architecture方法示例詳解
這篇文章主要為大家介紹了使用Node.js實(shí)現(xiàn)Clean?Architecture方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
nodejs結(jié)合socket.io實(shí)現(xiàn)websocket通信功能的方法
這篇文章主要介紹了nodejs結(jié)合socket.io實(shí)現(xiàn)websocket通信功能的方法,結(jié)合實(shí)例形式分析了nodejs結(jié)合socket.io實(shí)現(xiàn)websocket通信的具體步驟與相關(guān)操作技巧,需要的朋友可以參考下2018-01-01
簡(jiǎn)單模擬node.js中require的加載機(jī)制
大家都知道Node 采用的模塊化結(jié)構(gòu)是按照 CommonJS 規(guī)范,模塊與文件是一一對(duì)應(yīng)關(guān)系,即加載一個(gè)模塊,實(shí)際上就是加載對(duì)應(yīng)的一個(gè)模塊文件。這篇文章顯示簡(jiǎn)單的介紹了nodejs中require的加載機(jī)制,而后簡(jiǎn)單的模擬require函數(shù),有需要的朋友們下面來一起看看吧。2016-10-10
NodeJS 將文件夾按照存放路徑變成一個(gè)對(duì)應(yīng)的JSON的方法
這篇文章主要介紹了NodeJS 將文件夾按照存放路徑變成一個(gè)對(duì)應(yīng)的JSON的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-10-10
node.js中的events.emitter.removeListener方法使用說明
這篇文章主要介紹了node.js中的events.emitter.removeListener方法使用說明,本文介紹了events.emitter.removeListener的方法說明、語法、接收參數(shù)、使用實(shí)例和實(shí)現(xiàn)源碼,需要的朋友可以參考下2014-12-12
Node.js刷新session過期時(shí)間的實(shí)現(xiàn)方法推薦
下面小編就為大家?guī)硪黄狽ode.js刷新session過期時(shí)間的實(shí)現(xiàn)方法推薦。小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-05-05
探索node之事件循環(huán)的實(shí)現(xiàn)
這篇文章主要介紹了探索node之事件循環(huán)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10

