身份驗證
爲什麼需要
- http請求是無狀態的
- 無狀態指的就是一次用戶請求時,客戶端和服務端無法知道當前這個用戶要做什麼,是哪一個用戶,對於他們來說,每次都是一個新的請求
- 無狀態的原因,瀏覽器和服務器之間是利用socket套接字進行通信的,瀏覽器請求之後,服務器返回結果之後,就會關閉當前socket連接
session-cookie
服務端
npm i express-session
npm i cookie-parser
- 前端登錄成功後,後端把用戶相關信息(非敏感信息)放入session中,同時設置過期時間,會自動放入cookie中,返回給前端
- 此後,前端每次請求api接口時,cookie會自動攜帶給後端
const cookieParser = require(''cookie-parser') const session = require('express-session') app.use(session({ secret: "hfghsjdhwjewjek", // 加密字符串 cookie: {maxAge: 7 * 24 * 60 * 60 * 1000}, // 設置過期時間 resave: true, // 默認爲true,即使session沒有被修改,也會保存session saveUninitialized: false, // 默認爲true,無論有沒有session,cookie,每次都設置 })) // 登錄成功 req.session.login = true req.session.username = 'hello' // 在需要驗證的接口添加判斷 if (req.session.login) {} // 驗證成功 // 退出 app.get('/out', (req, res) => { req.session.destroy() res.redirect('/') })
jwt
步驟
- 用戶首次登錄成功後,服務端返回token(加密字符串),包含用戶信息
- 客戶端在以後的每次請求時候,都攜帶服務端返回的token進行請求(放在請求頭中傳給後端)
- 服務端接收到token時,需要對token進行驗證
服務端
const jwt = require('jsonwebtoken') const secret = 'hhdajhd' // 自定義的一串密鑰字符串 // 產生token function createToken(payload) { payload.ctime = Date.now() payload.exp = 7 * 24 * 60 * 60 * 1000 // 定義token過期時間 ... return jwt.sign(payload, secret) } // 校驗token function checkToken(token) { return new Promise((resolve, reject) => { jwt.verify(token, secret, (err, data) => { if (err) { reject('token驗證失敗') } resolve(data) }) }) } // 導出 module.exports = { createToken, checkToken }
token
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzY29wZSI6WyJzbWljIl0sImNvbXBhbnkiOiJQaGlsb3NvcGh5IiwiZXhwIjoxNTgwODkxNjA5LCJqdGkiOiI4NjY4YWRhMi00MjJhLTRkNmUtODZiZC04M2FkY2ZjZWZiNzAiLCJjbGllbnRfaWQiOiJzbWljIn0.AGkZm6dDf3SwX0kmdaWYC6CcCuaJlXh5LHGpRa1y-xo"
由三段組成
第一段,header頭部
第二段,載荷,存放用戶相關信息
第三段,簽名