Web開發(fā)模式
- 基于服務(wù)器渲染的傳統(tǒng)web開發(fā)模式
- 服務(wù)端渲染的概念,服務(wù)器發(fā)送給客戶端的HTNL頁面,是在服務(wù)器通過字符串的拼接,動態(tài)生成的,因此,客戶端不需要Ajax這樣的技術(shù)額外請求頁面的數(shù)據(jù)
優(yōu)點:
- 前端耗時少,有利于seo(就是爬蟲更容易爬取獲得信息,更有利于seo)
缺點:
- 占用服務(wù)端資源,請求過多,會對服務(wù)器造成壓力
- 不利于前后端分離,開發(fā)效率低
//服務(wù)器通過字符串的拼接,發(fā)送給前端
app.get("/user", function (req, res) {
const user ={name:'乞力馬扎羅',age:'24'}
// res.send()方法,可以把處理好的json內(nèi)容,發(fā)送給客戶端
res.send(`<h1>姓名:${user.name},年齡:${user.age}`)
})
- 基于前后端分離渲染的新型web開發(fā)模式
- 前后端分離二點開發(fā)模式,依賴于Ajax技術(shù)的廣泛應(yīng)用
- 就是后端只負責(zé)提供api接口,前端調(diào)用Ajax接口的開發(fā)模式
優(yōu)點:
- 開發(fā)體驗好,前端專注于UI頁面,后端專注于Api的開發(fā)
- 用戶體驗好,Ajax可以輕松實現(xiàn)頁面的局部刷新
- 減輕了服務(wù)器端的渲染壓力
缺點:
- 不利于SEO,因為完整的HTML頁面需要在客戶端動態(tài)拼接完成,所以爬蟲無法提取頁面的有效信息(解決方案,利用vue,React等前端的SSR技術(shù)能夠很好的解決該問題)
如何選擇Web開發(fā)模式
- 比如企業(yè)級網(wǎng)站,主要功能是展示而沒有復(fù)雜的交互,并且需要良好的SEO,這時就需要使用服務(wù)端渲染
- 類似后臺管理項目,交互性強,不需要考慮seo,那么就可以使用前后端分離的開發(fā)模式
- 當(dāng)然,有時候為了兼顧首頁的渲染速度和前后端分離的開發(fā)效率,一些網(wǎng)站采用首屏服務(wù)器渲染+其他頁面前后端分離的開發(fā)模式
身份認證
什么是身份認證
- 身份認證又稱身份驗證,鑒權(quán),是指通過一定的手段完成對用戶身份的確認
- web開發(fā)中,涉及到用戶身份的認證。例如各大網(wǎng)站的手機驗證碼登錄,郵箱密碼登錄,二維碼登錄
為什么要身份認證
- 身份認證的目的,是為了確認當(dāng)前所聲稱為某種身份的用戶,確實是所聲稱的用戶、
- 類似,取快遞的時候,拿出你的取件碼或手機尾號
不同開發(fā)模式的身份認證
基于服務(wù)器渲染和前后端分離的兩種開發(fā)模式,分別有不同的身份認證方案
- 服務(wù)端渲染推薦使用Session認證機制
- 前后端分離推薦使用JWT認證機制
Session認證機制
-
了解HTTP協(xié)議的無狀態(tài)性
- 指的是客戶端的每次http請求都是獨立的,連續(xù)多個請求之間沒有直接的關(guān)系,服務(wù)器不會主動保留每次HTTP請求的狀態(tài)
- 類似超市收銀員記不住每個來結(jié)算的客戶是否是VIP 如何突破HTTP的無狀態(tài)的限制
- 客戶端在登錄成功的時候,服務(wù)器給客戶端頒發(fā)一個登錄成功的標(biāo)識,這樣客戶端第二次登錄的時候,就可以攜帶這個標(biāo)識(Cookie),來告訴服務(wù)器我之前登錄過
- 類似超市為客戶辦理會員卡,收銀員通過會員卡來確認客戶是否是VIP
- 現(xiàn)實生活中的會員卡身份認證方式,在web開發(fā)中的專業(yè)術(shù)語叫做Cookie
-
什么是Cookie
- 1,Cookie是存儲在用戶游覽器中的一般不超過4kb的字符串,它由一個名稱(Name),一個值(Value)和其他幾個用于控制Cookie有效期,安全性,使用范圍的可選屬性組成
-
2,不同域名下的Cookie各自獨立,每當(dāng)客戶端發(fā)起請求,會自動把
當(dāng)前域名下所有
未過期的Cookie一同發(fā)送到服務(wù)器
- 自動發(fā)送,隨著請求自動發(fā)送
- 域名獨立,百度不能訪問淘寶下的cookie
- 過期時限,每個cookie都有有效期,過了就不會再發(fā)送了
- 4kb限制,每個cookie不能超過4kb Cookie在身份認證中的作用
- 1,客戶端第一次請求服務(wù)器的時候,服務(wù)器通過響應(yīng)頭的形式,向客戶端發(fā)送一個身份認證的Cookie
- 2,客戶端會自動將Cookie保存在游覽器中
- 3,隨后,客戶端游覽器每次請求服務(wù)器的時候,游覽器會自動將身份認證相關(guān)的所有Cookie,通過請求頭的形式發(fā)送給服務(wù)器,
- 4,服務(wù)器即可驗明客戶端的身份
-
Cookie不具有安全性
- 因為Cookie是存儲在游覽器中,而且游覽器也提供了讀寫cookie的API,因此Cookie很容易被偽造,不具有安全性
- 因此不建議服務(wù)器將重要的隱私數(shù)據(jù),通過cookie的形式發(fā)送給游覽器
- 所以,千萬不要使用Cookie存儲重要且隱私的數(shù)據(jù),比如用戶的身份信息,密碼
提高身份認證的安全性
- 類似,為了防止客戶偽造會員卡,收銀員在拿到客戶出示的會員卡之后,可以在收銀機上進行刷卡認證,只有收銀機確認存在的會員卡,才可以被正常使用,也就是會員卡+刷卡認證
- ‘會員卡+刷卡認證’ 的 這種理念,就是Session的認證機制的精髓
Session的工作原理
Express中使用Session認證
- 安裝Express-session中間件,npm i express-session
在Express項目中,只需要安裝中間件,即可在項目中使用Session認證
- 配置express-session中間件
express-session中間件安裝成功后,需要通過app.use()來注冊session中間件
//express-session中間件
//導(dǎo)入session中間件
const session = require('express-session')
//注冊session
app.use(session({
secret: "key", //值,負責(zé)對session加密
resave: false, //固定寫法
saveUninitialized: true, //固定寫法
}))
- 向session中存數(shù)據(jù)
- 配置成功后,即可通過req.session來訪問和使用session對象,從而存儲用戶的關(guān)鍵信息
- 只有配置了express-session這個中間件,才能通過req點出來session這個屬性
- 如果post請求,配置這個app.use(express.urlencoded({extended:false})),不然post請求是空
//express-session中間件
//導(dǎo)入session中間件
const session = require('express-session')
// 導(dǎo)入express
const express = require('express')
// 創(chuàng)建web服務(wù)器
const app = express()
// 啟動文本服務(wù)器
app.listen(80,()=>{
console.log("80服務(wù)器啟動")
})
//注冊session
app.use(session({
secret: "key", //值,負責(zé)對session加密
resave: false, //固定寫法
saveUninitialized: true, //固定寫法
}))
//配置這個,不然post請求是空
app.post('/login', (req, res) => {
if (req.body.name !== '乞力馬扎羅' || req.body.password !== '111111') {
return res.send({
'status': 0,
msg: "登錄失敗"
})
}
//只有配置了express-session這個中間件,才能通過req點出來session這個屬性
//通過 req.session追加任何屬性
req.session.user = req.body
req.session.islogin = true
res.send({
'status': 1,
msg: "登錄成功"
})
})
- 向session中取數(shù)據(jù)
//向session中取數(shù)據(jù)
app.post('/getuserinfo', (req, res) => {
console.log(req.session.user)
// 判斷用戶是否登錄
if (!req.session.islogin) {
res.send({
'status': 0,
msg: "請登錄"
})
return
}
res.send({'status':1, data:req.session.user})
})
- 清空session
- 調(diào)用req.session.destroy()函數(shù),即可清空服務(wù)器保存的session信息·
- 只會清空調(diào)用這個的當(dāng)前用戶的session信息,而不是清空所有的session信息
- 調(diào)用場景,退出登錄
app.post('/outlogin', (req, res) => {
req.session.destroy()
res.send({'status':1, msg:'退出成功'})
})
Session認證機制的局限性
- session認證機制需要配合Cookie才能實現(xiàn)
- 由于cookie默認不支持跨域訪問,所以,當(dāng)涉及到前端跨域請求后端接口的時候,需要做很多額外的配置
- 才能實現(xiàn)跨域session認證
- 注意:
- 當(dāng)前端請求后端接口不存在跨域問題的時候,推薦使用session身份認證機制
- 當(dāng)前端需要跨域請求后端接口的時候,不推薦使用Seesion身份認證機制,推薦使用JWT認證機制
JWT認證機制
JWT,全稱:JSON Web Token,是目前最流行的跨域認證解決方案
JWT的工作原理
JWT的組成部分
- JWT通常由三部分組成,分別是Header(頭部),Payload(有效荷載),Signature(簽名)
- 三者之間由英文的.連接
- 格式:Header.Payload.Signature
- Payload部分才是真正的用戶信息,它是用戶信息經(jīng)過加密之后生成的字符串
- Header部分和Signature部分是安全性相關(guān)的部分,只是為了保證token的安全性
- 以/api開頭的請求路徑,不需要訪問權(quán)限
- 以/my開頭的請求路徑,需要在請求頭中攜帶Authorization身份認證,才能正常訪問成功
Authorization: Bearer <token>
Express中使用JWT
- 安裝JWT相關(guān)的包
npm install jsonwebtoken express-jwt
- jsonwebtoken 用于生成JWT字符串
- express-jwt用于將JWT字符串解析還原成JSON對象
- 導(dǎo)入包
const jwt = require("jsonwebtoken")
const expressjwt = require("express-jwt")
定義secret秘鑰
- 為了保證JWT字符串的安全性,防止JWT在網(wǎng)路傳輸錯過成中被別人破解,我們需要專門定義一個用于加密和解密的Secert秘鑰
- 當(dāng)生成JWT字符串的時候,需要使用secret秘鑰對用戶的信息進行加密,最終等到加密好的JWT字符串
- 當(dāng)把JWT字符串解析還原成JSON對象的時候,需要serect秘鑰進行解密
在登錄成功后生成JWT字符串
const jwt = require("jsonwebtoken")
const {expressjwt} = require("express-jwt")
//定義secret秘鑰,
const secretKey="adminpossword"
app.post('/jwtlogin', (req, res) => {
let user=req.body
if (req.body.name !== '乞力馬扎羅' || req.body.password !== '111111') {
return res.send({
'status': 0,
msg: "登錄失敗"
})
}
//調(diào)用jwt.sign()生成JWT字符串,三個參數(shù)分別是,用戶信息對象,加密秘鑰,配置對象(expiresIn代表token有效期)
res.send({
'status': 1,
msg: "登錄成功",
token:jwt.sign(user,secretKey,{expiresIn:'30s'})
})
})
將JWT字符串還原為JSON對象
- 客戶端每次在訪問哪些有權(quán)限接口的時候,都需要主動通過請求頭中的AUthirization字段,將token字符串發(fā)送到服務(wù)器進行身份驗證
- 此時,服務(wù)器通過express.Jwt這個中間件,自動將客戶端發(fā)送過來的token解析還原成JSON對象
// 1,使用app.use()注冊
// 2,expressjwt({secret:secretKey})就是用來解析的中間件
// 3,.unless({path:[/^\/api\//]})用來指定哪些接口不需要訪問權(quán)限
//4,algorithms:['HS256']必寫
// 配置過 express-jwt 可通過 req.auth 獲取token信息
app.use(expressjwt({ secret: secretKey, algorithms: ["HS256"] }).unless({ path: [/^\/api\//]}))
通過req.user對象,來訪問從JWT字符串中解析出來的用戶信息
- 配置請求頭Authorization:Bearer+空格+登錄后的token
- 訪問前一定得全局配置上面的app.use(expressjwt({ secret: secretKey, algorithms: [“HS256”] }).unless({ path: [/^/api//]}))
app.post('/getuser', (req, res) => {
console.log(req.user)
res.send({
status: 1,
msg: "成功",
data:req.auth
})
})
文章來源:http://www.zghlxwxcb.cn/news/detail-410764.html
捕獲解析JWT失敗后的產(chǎn)生的錯誤
- 檢驗token過期或者不合法,通過express錯誤中間件,捕獲到這個問題
- 錯誤中間件需放置在所有路由之后
//錯誤中間件
app.use((err, req, res, next) => {
console.log(err)
if (err.name === 'UnauthorizedError') {
return res.send({
status: 401,
message: "無效token"
})
}
res.send({
status: 500,
message: "未知錯誤"
})
})
文章來源地址http://www.zghlxwxcb.cn/news/detail-410764.html
到了這里,關(guān)于【Node.js】身份認證,Cookie和Session的認證機制,express中使用session認證和JWT認證的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!