1) 介紹
所謂會(huì)話控制就是 對(duì)會(huì)話進(jìn)行控制
HTTP 是一種無(wú)狀態(tài)的協(xié)議,它沒(méi)有辦法區(qū)分多次的請(qǐng)求是否來(lái)自于同一個(gè)客戶端, 無(wú)法區(qū)分用戶
而產(chǎn)品中又大量存在的這樣的需求,所以我們需要通過(guò) 會(huì)話控制
來(lái)解決該問(wèn)題
常見(jiàn)的會(huì)話控制技術(shù)有三種:
-
cookie
-
session
-
token
2) cookie
cookie 是什么
cookie 是 HTTP 服務(wù)器發(fā)送到用戶瀏覽器并保存在本地的一小塊數(shù)據(jù)
- cookie 是保存在瀏覽器端的一小塊數(shù)據(jù)
- cookie 是按照域名劃分保存的
簡(jiǎn)單示例:
域名 | cookie |
---|---|
www.baidu.com | a=100; b=200 |
www.bilibili.com | xid=1020abce121; hm=112411213 |
jd.com | x=100; ocw=12414cce |
cookie 的特點(diǎn)
瀏覽器向服務(wù)器發(fā)送請(qǐng)求時(shí),會(huì)自動(dòng)將 當(dāng)前域名下
可用的 cookie 設(shè)置在請(qǐng)求頭中,然后傳遞給服務(wù)器
這個(gè)請(qǐng)求頭的名字也叫 cookie
,所以將 cookie 理解為一個(gè) HTTP 的請(qǐng)求頭也是可以的
cookie 的代碼操作
express 中可以使用 cookie-parser
進(jìn)行處理
//導(dǎo)入express
const express = require("express");
const cookieParser = require("cookie-parser");
const app = express();
app.use(cookieParser());
app.get("/set-cookie", (req, res) => {
//res.cookie("name", "zhangsan"); // 會(huì)在瀏覽器關(guān)閉時(shí)銷毀
res.cookie("name", "lisi", {maxAge: 60 * 1000});
res.cookie("theme", "blue");
res.send("home");
});
app.get("/remove-cookie", (req, res) => {
res.clearCookie("name");
res.send("remove success");
});
// get cookie
app.get("/get-cookie", (req, res) => {
console.log(req.cookies);
res.send(`Welcome ${req.cookies.name}`);
});
app.listen(3000);
3) session
session 是什么
session 是保存在 服務(wù)器端的一塊數(shù)據(jù)
,保存當(dāng)前訪問(wèn)用戶的相關(guān)信息
session 的作用
實(shí)現(xiàn)會(huì)話控制,可以識(shí)別用戶的身份,快速獲取當(dāng)前用戶的相關(guān)信息
session 運(yùn)行流程
填寫賬號(hào)和密碼校驗(yàn)身份,校驗(yàn)通過(guò)后創(chuàng)建 session 信息
,然后將 session_id
的值通過(guò)響應(yīng)頭返回給瀏覽器
有了 cookie,下次發(fā)送請(qǐng)求時(shí)會(huì)自動(dòng)攜帶 cookie,服務(wù)器通過(guò) cookie
中的 session_id
的值確定用戶的身份
session 的代碼操作
express 中可以使用 express-session 對(duì) session 進(jìn)行操作
//導(dǎo)入express
const express = require("express");
//1. 安裝包 npm i express-session connect-mongo
//2. 引入 express-session connect-mongo
const session = require("express-session");
const MongoStore = require('connect-mongo');
const e = require("express");
const app = express();
//3. 設(shè)置 session 的中間件
app.use(session({
name: 'sid', //設(shè)置cookie的name,默認(rèn)值是:connect.sid
secret: 'atguigu', //參與加密的字符串(又稱簽名)加鹽
saveUninitialized: false, //是否為每次請(qǐng)求都設(shè)置一個(gè)cookie用來(lái)存儲(chǔ)session的id
resave: true, //是否在每次請(qǐng)求時(shí)重新保存session
store: MongoStore.create({
mongoUrl: 'mongodb://127.0.0.1:27017/bilibili' //數(shù)據(jù)庫(kù)的連接配置
}),
cookie: {
httpOnly: true, // 開啟后前端無(wú)法通過(guò) JS 操作
maxAge: 1000 * 60 * 5 // 這一條 是控制 sessionID 的過(guò)期時(shí)間的?。?!
},
}))
app.get("/", (req, res) => {
res.send("home");
});
// 設(shè)置 session
app.get("/login", (req, res) => {
// username=admin&password=admin
if(req.query.username === 'admin' && req.query.password === 'admin'){
// 設(shè)置 session
req.session.username = 'admin';
req.session.sid = '1234rtgfds';
res.send("登錄成功");
}
});
// session讀取
app.get("/cart", (req, res) => {
// 檢測(cè)session
if (req.session.username){
res.send(`Welcome ${req.session.username}`);
} else {
res.send("請(qǐng)先登錄");
}
});
// session銷毀
app.get("/logout", (req, res) => {
req.session.destroy(() => {
res.send("退出成功");
});
});
app.listen(3000);
4) session 和 cookie 的區(qū)別
cookie 和 session 的區(qū)別主要有如下幾點(diǎn):
1.存在的位置
- cookie:瀏覽器端
- session:服務(wù)端
2.安全性
- cookie 是以明文的方式存放在客戶端的,安全性相對(duì)較低
- session 存放于服務(wù)器中,所以安全性
相對(duì)
較好
3.網(wǎng)絡(luò)傳輸量
- cookie 設(shè)置內(nèi)容過(guò)多會(huì)增大報(bào)文體積, 會(huì)影響傳輸效率
- session 數(shù)據(jù)存儲(chǔ)在服務(wù)器,只是通過(guò) cookie 傳遞 id,所以不影響傳輸效率
4.存儲(chǔ)限制
- 瀏覽器限制單個(gè) cookie 保存的數(shù)據(jù)不能超過(guò) 4K ,且單個(gè)域名下的存儲(chǔ)數(shù)量也有限制
- session 數(shù)據(jù)存儲(chǔ)在服務(wù)器中,所以沒(méi)有這些限制
5) token
token 是什么
token
是服務(wù)端生成并返回給 HTTP 客戶端的一串加密字符串, token
中保存著 用戶信息
token 的作用
實(shí)現(xiàn)會(huì)話控制,可以識(shí)別用戶的身份,主要用于移動(dòng)端 APP
token 的工作流程
填寫賬號(hào)和密碼校驗(yàn)身份,校驗(yàn)通過(guò)后響應(yīng) token,token 一般是在響應(yīng)體中返回給客戶端的
后續(xù)發(fā)送請(qǐng)求時(shí),需要手動(dòng)將 token 添加在請(qǐng)求報(bào)文中,一般是放在請(qǐng)求頭中
token 的特點(diǎn)
- 服務(wù)端壓力更小
- 數(shù)據(jù)存儲(chǔ)在客戶端
- 相對(duì)更安全
- 數(shù)據(jù)加密
- 可以避免 CSRF(跨站請(qǐng)求偽造)
- 擴(kuò)展性更強(qiáng)
- 服務(wù)間可以共享
- 增加服務(wù)節(jié)點(diǎn)更簡(jiǎn)單
JWT
JWT(JSON Web Token )是目前最流行的跨域認(rèn)證解決方案,可用于基于 token 的身份驗(yàn)證
JWT 使 token 的生成與校驗(yàn)更規(guī)范文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-829477.html
可以使用 jsonwebtoken
包 來(lái)操作 token文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-829477.html
const jwt = require('jsonwebtoken');
// 生成/創(chuàng)建 token
// let token = jwt.sign(用戶數(shù)據(jù),加密字符串, 配置對(duì)象);
let token = jwt.sign({
username: 'zhangsan',
}, 'atguigu', {
expiresIn: 60 // 單位是秒
});
console.log(token);
// 校驗(yàn) token
let t = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InpoYW5nc2FuIiwiaWF0IjoxNzA3NzMxMDgyLCJleHAiOjE3MDc3MzExNDJ9.gyRxrxatBBL89twd5FYfrfNKYQ98d00NuwnnnF2_iNg";
jwt.verify(t, 'atguigu', (err, data) => {
if (err) {
console.log('token 驗(yàn)證失敗');
return;
}
console.log('token 驗(yàn)證成功');
console.log(data);
});
到了這里,關(guān)于Node.js開發(fā)-會(huì)話控制的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!