Express實(shí)現(xiàn)Session身份認(rèn)證的示例代碼
Cookie
HTTP
HTTP(Hyper Text Transfer Protocol,超文本傳輸模式)屬于無(wú)狀態(tài)協(xié)議,在同一個(gè)連接中,兩個(gè)執(zhí)行成功的請(qǐng)求之間是沒(méi)有關(guān)系的。這就帶來(lái)了一個(gè)問(wèn)題,用戶沒(méi)有辦法在同一個(gè)網(wǎng)站中進(jìn)行連續(xù)的交互。例如:
在一個(gè)電商網(wǎng)站里,用戶把某個(gè)商品加入到購(gòu)物車,切換一個(gè)頁(yè)面后再次添加了商品,這兩次添加商品的請(qǐng)求之間沒(méi)有關(guān)聯(lián),瀏覽器無(wú)法知道用戶最終選擇了哪些商品。而使用 HTTP 的標(biāo)頭(請(qǐng)求頭及響應(yīng)頭)擴(kuò)展,HTTP Cookie 就可以解決這個(gè)問(wèn)題。把 Cookie 添加到標(biāo)頭中,創(chuàng)建一個(gè)會(huì)話讓每次請(qǐng)求都能共享相同的上下文信息,達(dá)成相同的狀態(tài)。
Cookie
Cookie 是一段不超過(guò) 4KB 的小型文本數(shù)據(jù),由一個(gè)名稱(Name)以及其對(duì)應(yīng)的值(Value)和其它幾個(gè)用于控制 Cookie 有效期、安全性、使用范圍的可選屬性組成。
服務(wù)器端
如果一個(gè)客戶是首次登錄該網(wǎng)頁(yè)的,那么在本次登錄成功后,服務(wù)器端將向客戶端發(fā)送一個(gè) Cookie ,其中保存了用戶的登錄信息。
客戶端
Cookie 保存了你的登錄信息,瀏覽器會(huì)通過(guò)域名來(lái)劃分瀏覽器中所有的 Cookie。在你訪問(wèn)一個(gè)網(wǎng)頁(yè)時(shí),瀏覽器會(huì)首先查看瀏覽器中是否存儲(chǔ)了與該域名相關(guān)的 Cookie。如果存在,則在向該域名發(fā)起請(qǐng)求時(shí)將攜帶與該域名相關(guān)的所有的未過(guò)期 Cookie。
Session
Session 是基于 Cookie 的,但服務(wù)器生成的 Cookie 是一段無(wú)意義的字符串(稱為 SessionID)。在訪問(wèn)網(wǎng)頁(yè)時(shí)你將發(fā)送與該網(wǎng)頁(yè)相關(guān)的 Cookie,即 SessionID。服務(wù)器端接收到該數(shù)據(jù)后將在服務(wù)器中查詢與該 SessionID 相關(guān)的 Session 對(duì)象并通過(guò)該對(duì)象中存儲(chǔ)的用戶信息來(lái)決定對(duì)該客戶端的行為。
Session VS Cookie
- Session 將用戶信息存儲(chǔ)在服務(wù)器端,而 Cookie 將用戶信息存儲(chǔ)在客戶端。因此,Cookie 不適合用于保存重要的數(shù)據(jù)。
- Session 將用戶數(shù)據(jù)保存在服務(wù)器端,這會(huì)導(dǎo)致服務(wù)器端的工作量增大。
- 攻擊者可以通過(guò)分析 Cookie 中的數(shù)據(jù)來(lái)進(jìn)行 Cookie 欺騙。而使用 Session 進(jìn)行身份認(rèn)證時(shí),用戶的相關(guān)信息保存在服務(wù)器中,因此不用擔(dān)心會(huì)被欺騙。
Express 實(shí)現(xiàn) Session 身份認(rèn)證
獲取
在 Express 中,如果你希望使用 Session 進(jìn)行身份認(rèn)證,你可以通過(guò)第三方中間件 express-session 來(lái)實(shí)現(xiàn)。如果你使用的是 npm(NodeJS Package Manager) 包管理器,那么你可以通過(guò)如下命令來(lái)下載并安裝第三方中間件:
npm install express-session
配置
// 導(dǎo)入第三方提供的 express-session 中間件
const session = require('express-session');
// 配置 express-session 中間件
app.use(session({
? ? secret: 'RedHeart',
? ? resave: false,
? ? saveUninitialized: true
}))其中:
- app.use() 函數(shù)用于將中間件注冊(cè)為全局中間件。對(duì)于客戶端發(fā)送到服務(wù)器端的任意類型的請(qǐng)求,如果該請(qǐng)求中沒(méi)有包含 Cookie,服務(wù)器端將向該客戶端發(fā)送 Cookie 。
- 對(duì)于傳遞給中間件函數(shù) session() 的參數(shù)對(duì)象,有:
| 項(xiàng)目 | 描述 |
|---|---|
| secret | 用于為生成的 SessionID 進(jìn)行簽名。 |
| name | 用于設(shè)置發(fā)送到客戶端的 Cookie 的名稱。 |
對(duì)于 resave: false 及 saveUninitialized: true 的作用 還沒(méi)有搞清楚,但網(wǎng)上的相關(guān)資料均推薦這樣設(shè)置。
登錄
const express = require('express');
// 導(dǎo)入第三方提供的 express-session 中間件
const session = require('express-session');
const app = express();
// 監(jiān)聽(tīng)本機(jī) 9090 端口
app.listen(9090);
// 配置 express-session 中間件
app.use(session({
? ? secret: 'RedHeart',
? ? resave: false,
? ? saveUninitialized: true
}))
// 設(shè)置登錄頁(yè)面的路由
app.get('/login', (req, res) => {
? ? // 判斷 GET 請(qǐng)求中的查詢字符串中的參數(shù)的值是否符合要求
? ? if(req.query.username === 'redheart' && req.query.password === 'twomoons'){
? ? ? ? // 將用戶信息添加至 Session 中
? ? ? ? req.session.user = req.query;
? ? ? ? // 標(biāo)記當(dāng)前用戶目前處于登錄狀態(tài)
? ? ? ? req.session.isLogin = true;
? ? ? ? res.send('{ WIN }')
? ? }else{
? ? ? ? res.send('{ LOSE }');
? ? }
})執(zhí)行效果
在執(zhí)行上述代碼后,你可以通過(guò)訪問(wèn) http://127.0.0.1:9090/login/?username=redheart&password=twomoons 來(lái)進(jìn)行登錄。嘗試登錄后,若頁(yè)面中顯現(xiàn)字符串 { WIN } ,表明該用戶已經(jīng)登錄成功。
主頁(yè)
向前一個(gè)示例中添加如下代碼:
// 設(shè)置主頁(yè)路由
app.get('/home', (req, res) => {
// 判斷客戶端的 Session 狀態(tài)是否為 true
// 如果服務(wù)器端還未為該客戶端分配 SessionID
// 則 req.session.isLogin 為 undefined 。
if(req.session.isLogin){
res.send('{ WIN }');
}else{
res.send('{ LOSE }');
}
})
執(zhí)行效果
在通過(guò)訪問(wèn) http://127.0.0.1:9090/login/?username=redheart&password=twomoons 登錄成功后,訪問(wèn) http://127.0.0.1:9090/home 你將于頁(yè)面中觀察到字符串 { WIN }。你可以嘗試刷新該頁(yè)面,你會(huì)發(fā)現(xiàn)顯示的字符串并沒(méi)有變成 { LOSE },這說(shuō)明服務(wù)器端已經(jīng)通過(guò) SessionID 記住了你。
退出登錄
你可以通過(guò)調(diào)用 req.session.destroy() 來(lái)清除 當(dāng)前 客戶端保存在服務(wù)器端的 Session 數(shù)據(jù)。SessionID 仍保存在客戶端瀏覽器中,但已經(jīng)失效。
app.get('/logout', (req, res) => {
req.session.destroy();
res.send('{ WIN }');
})
代碼總匯
const express = require('express');
// 導(dǎo)入第三方提供的 express-session 中間件
const session = require('express-session');
const app = express();
// 監(jiān)聽(tīng)本機(jī) 9090 端口
app.listen(9090);
// 配置 express-session 中間件
app.use(session({
? ? secret: 'RedHeart',
? ? resave: false,
? ? saveUninitialized: true
}))
// 設(shè)置主頁(yè)路由
app.get('/home', (req, res) => {
? ? // 判斷客戶端的 Session 狀態(tài)是否為 true
? ? // 如果服務(wù)器端還未為該客戶端分配 SessionID
? ? // 則 req.session.isLogin 為 undefined 。
? ? if(req.session.isLogin){
? ? ? ? res.send('{ WIN }');
? ? }else{
? ? ? ? res.send('{ LOSE }');
? ? }
})
// 設(shè)置登錄頁(yè)面的路由
app.get('/login', (req, res) => {
? ? // 判斷 GET 請(qǐng)求中的查詢字符串中的參數(shù)的值是否符合要求
? ? if(req.query.username === 'redheart' && req.query.password === 'twomoons'){
? ? ? ? // 將用戶信息添加至 Session 中
? ? ? ? req.session.user = req.query;
? ? ? ? // 標(biāo)記當(dāng)前用戶目前處于登錄狀態(tài)
? ? ? ? req.session.isLogin = true;
? ? ? ? res.send('{ WIN }')
? ? }else{
? ? ? ? res.send('{ LOSE }');
? ? }
})
app.get('/logout', (req, res) => {
? ? req.session.destroy();
? ? res.send('{ WIN }');
})到此這篇關(guān)于Express實(shí)現(xiàn)Session身份認(rèn)證的示例代碼的文章就介紹到這了,更多相關(guān)Express Session身份認(rèn)證內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于沒(méi)有徹底清除node和npm的解決方法
最近因?yàn)閚pm和node的版本不匹配遇到了許多困難,比如更新npm的版本,結(jié)果它給報(bào)錯(cuò)了,查閱了好多資料,發(fā)現(xiàn)就是node和npm卸載的時(shí)候,還有殘留,所以本文給大家介紹了關(guān)于沒(méi)有徹底清除node和npm的解決方法,需要的朋友可以參考下2024-03-03
Nodejs如何進(jìn)行性能監(jiān)控和分析優(yōu)化
Node.js應(yīng)用可能因?yàn)楦卟l(fā)、內(nèi)存泄漏、CPU密集型任務(wù)等原因?qū)е滦阅芟陆?影響用戶體驗(yàn)甚至系統(tǒng)穩(wěn)定性,通過(guò)性能監(jiān)控和分析,我們可以及時(shí)發(fā)現(xiàn)潛在問(wèn)題,并針對(duì)性地進(jìn)行優(yōu)化,確保系統(tǒng)正常運(yùn)行且具備良好的性能表現(xiàn)2024-06-06
nodejs使用express獲取get和post傳值及session驗(yàn)證的方法
這篇文章主要介紹了nodejs使用express獲取get和post傳值及session驗(yàn)證的方法,結(jié)合實(shí)例形式分析了nodejs使用express實(shí)現(xiàn)獲取get和post傳值及session驗(yàn)證功能的具體操作步驟與注意事項(xiàng),需要的朋友可以參考下2017-11-11
Node.js接入DeepSeek實(shí)現(xiàn)流式對(duì)話功能
隨著人工智能技術(shù)的發(fā)展,越來(lái)越多的服務(wù)和應(yīng)用開(kāi)始集成AI能力以提升用戶體驗(yàn),本文將介紹如何通過(guò)Node.js接入DeepSeek提供的API服務(wù),特別是其聊天完成(Chat?Completions)功能,為您的應(yīng)用增添智能對(duì)話能力,需要的朋友可以參考下2025-02-02
node pnpm修改默認(rèn)包的存儲(chǔ)路徑(操作方法)
PNPM是一個(gè)新的包管理工具,也是NPM的另一個(gè)替代方案,與NPM不同,PNPM使用符號(hào)鏈接(symlink)而不是復(fù)制文件來(lái)安裝包,這篇文章主要介紹了node pnpm修改默認(rèn)包的存儲(chǔ)路徑,需要的朋友可以參考下2024-05-05
使用node.js半年來(lái)總結(jié)的 10 條經(jīng)驗(yàn)
從3月初來(lái)到帝都某創(chuàng)業(yè)公司的服務(wù)器團(tuán)隊(duì)實(shí)習(xí),到現(xiàn)在已接近半年的時(shí)間。PS: 已轉(zhuǎn)正,服務(wù)器端用的 Node。2014-08-08
Node.js 使用流實(shí)現(xiàn)讀寫同步邊讀邊寫功能
本文通過(guò)代碼給大家介紹了Node.js 使用流實(shí)現(xiàn)讀寫同步邊讀邊寫功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的額朋友參考下吧2017-09-09
使用iojs的jsdom庫(kù)實(shí)現(xiàn)同步系統(tǒng)時(shí)間
本文給大家分享的是使用iojs的jsdom庫(kù)實(shí)現(xiàn)與http://open.baidu.com/special/time/ 同步系統(tǒng)時(shí)間。思路非常的清晰,這里推薦給大家,有需要的小伙伴可以參考下。2015-04-04
使用 Node.js 模擬滑動(dòng)拼圖驗(yàn)證碼操作的示例代碼
本篇文章主要介紹了使用 Node.js 模擬滑動(dòng)驗(yàn)證碼操作的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-11

