起因:http請求是無狀態的 , 這意味着每個請求都是獨立的, 我們給服務器發送 HTTP 請求之后,服務器根據請求,會給我們發送數據過來,但是,發送完,不會記錄任何信息。無狀態無連接,具體如何理解。
解決方案:
1、cookie+session
cookie:前端;session:服務器端
實現過程如下:
a、前端登錄成功,后端會發布一個加密字符串(用戶相關信息)給前端,( ⚠️ 自動在前端存cookie )
b、前端調用其他接口,前端保存起來,之后每次請求的時候,將加密字符串作為參數,傳遞給服務器端(⚠️ cookie自動傳遞 )
c、服務器端拿到字符串進行解密,根據權限進行驗證,如果驗證通過的話,就可以接着執行接口邏輯
需要插件:
cookie-parse: 解析cookie數據
express-session: https://www.npmjs.com/package/express-session
const cookieParse=require('cookie-parser')
const session = require('express-session')
// seesion 整體配置 app.use(session({ secret: 'sjfsdkjflajf', //為了安全性的考慮設置secret屬性 cookie: {maxAge: 60 * 1000*24*7 }, //設置過期時間7天 resave: true, // 即使 session 沒有被修改,也保存 session 值,默認為 true saveUninitialized: false, //無論有沒有session cookie,每次請求都設置個session cookie ,默認給個標示為 connect.sid }));
后端存session👇

登錄成功,將用戶信息存到session
調用其他接口時,后端會取session,看登錄狀態是否存在

前端界面如何處理👇

補充:如何注銷session:
退出登錄的接口部分👇

前端部分:

易錯點⚠️:注意一定不要產生跨域(localhost&127.0.0.1)!否則cookie,session無法使用~~
以上就是原理,具體細節可能還會涉及到加密算法之類的。
限制性:由於域名和api不一樣的情況大有存在,session和cookie跨域限制,所以可以考慮方案二 JWT。
2、JWT安全驗證(https://jwt.io/)
token :header.payload.密鑰

jsonwebtoken : 用npm安裝,它是實現加密解密的方法。
token.js
const jwt = require('jsonwebtoken')
//步驟一:產生token的私鑰
let screat = 'sflsdjfl;ajflsjflasjflasjfoas'
let payload = { //不能放重要敏感信息
us: 123,
ps: 456
}
//傳遞的數據
//步驟二:通過hs256加密 ,產生一個token
// let token=jwt.sign(payload,screat) //hs256加密 數據 載荷 screat
let token = 'hbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1cyI6MTIzLCJwcyI6NDU2LCJpYXQiOjE1NTg0MjE4OTB9.8TEQ_dMFzckiMVE--7XP-jjmnl7QE68qz0bptEMn5vs'
// console.log(token)
//步驟三:驗證token的合法性
jwt.verify(token, screat, (err, data) => {//screat,密鑰
console.log(err)
console.log(data)
})
把以上代碼封裝成模塊,jwt.js
const jwt = require('jsonwebtoken')
const scrict = 'sdjfksdjflajflasjflasjflksf'
function creatToken(palyload) {
// 生成 jwt 邏輯
palyload.ctime = Date.now()// ctime創建時間
palyload.exp = 1000 * 60 * 24 * 7 //設置超時邏輯
return jwt.sign(palyload, scrict)
}
function checkToken(token) {
return new Promise((resovle, reject) => {
jwt.verify(token, scrict, (err, data) => {
if (err) {
reject('token 驗證失敗')
}
resovle(data)
})
})
}
module.exports = {
creatToken, checkToken
}
如何在 接口中 使用jwt.js👇
const JWT = require('../utils/jwt')//引入
router.post('/login', (req, res) => {
let {us, ps} = req.body
if (!us || !ps) {
return res.send({err: -1, msg: '參數錯誤'})
}
// {us:us,ps:ps} === {us,ps}
User.find({us, ps})
.then((data) => {
if (data.length > 0) {
// 登錄成功后將用戶的相關信息存到session
// req.session.login=true
// req.session.name=us
let token = JWT.creatToken({login: true, name: us})
res.send({err: 0, msg: '登錄ok', token: token})
} else {
res.send({err: -2, msg: '用戶名或密碼不正確'})
}
// console.log(data)
})
.catch((err) => {
return res.send({err: -1, msg: '內部錯誤'})
})
})
app.use('/food', (req, res, next) => {
console.log(req.body)
let {token} = req.body
JWT.checkToken(token)
.then((data) => {
next()
})
.catch((err) => {
res.send({err: -998, msg: 'token 非法'})
})
// if(req.session.login){
// next()
// }else{
// res.send({err:-999,msg:'請先登錄'})
// }
}, fooodRouter)
