傳統(tǒng)的Session驗(yàn)證
起初的驗(yàn)證方式是存在于服務(wù)器的蔓罚,用戶登錄進(jìn)來以后阳掐,服務(wù)器判斷成功,將數(shù)據(jù)存進(jìn)session里面武福,向用戶返回一個(gè)sessionID议双。這樣的弊端是,假如用戶基數(shù)特別大捉片,每登錄一個(gè)用戶平痰,就要存儲(chǔ)一條,對(duì)服務(wù)器的內(nèi)存壓力比較大伍纫。
基于Token的驗(yàn)證方法
基于Token的驗(yàn)證方法是無狀態(tài)的宗雇,因此我們就不用把信息存在服務(wù)器中了。
Token可以通過請(qǐng)求頭傳輸莹规,所以他可以在任何一種http請(qǐng)求中被發(fā)送到服務(wù)器中赔蒲。
Token的驗(yàn)證流程
客戶端發(fā)送用戶、密碼到服務(wù)器。
服務(wù)器接收到信息之后和數(shù)據(jù)庫進(jìn)行比對(duì)舞虱,驗(yàn)證成功后欢际,生成一段有時(shí)效的Token字符串,向客戶端返回登陸成功信息以及Token字符串矾兜。
客服端接收到信息损趋,將Token存儲(chǔ)在Local Storage或者Cookies中。
客服端再向服務(wù)器發(fā)送請(qǐng)求時(shí)椅寺,將Token放在請(qǐng)求頭中浑槽。
服務(wù)器先解析請(qǐng)求頭中的Token,如果解析成功,那么就進(jìn)入業(yè)務(wù)邏輯中返帕,如果不成功返回錯(cuò)誤信息桐玻。
nodeJS(express) + jwt(jsonwebtoken)
首先安裝 jsonwebtoken
npm install jsonwebtoken -S
然后在服務(wù)器中創(chuàng)建一個(gè)js文件,可以自行命名荆萤,我在這里命名為jwt.js
// 引入模塊依賴
const fs = require('fs');
const path = require('path');
const jwt = require('jsonwebtoken');
// 創(chuàng)建 token 類
class Jwt {
constructor(data, key, minute) {
this.data = data;
this.keyword = key;
this.minute = minute || 30
}
//生成token
generateToken() {
let data = this.data;
let minute = this.minute
let keyword = this.keyword
let created = Math.floor(Date.now() / 1000);
let exp = created + 60 * minute;
let cert = fs.readFileSync(path.join(__dirname, '../pem/rsa_private_key.pem')); //私鑰 可以自己生成
let token = jwt.sign({
data: {
'id': data,
"key": keyword
},
exp
}, cert, {
algorithm: 'RS256'
});
return token;
}
// 校驗(yàn)token
verifyToken() {
let token = this.data
let cert = fs.readFileSync(path.join(__dirname, '../pem/rsa_public_key.pem')); //公鑰 可以自己生成
let res;
try {
let result = jwt.verify(token, cert, {
algorithms: ['RS256']
}) || {};
let {
exp = 0
} = result, current = Math.floor(Date.now() / 1000);
if (current <= exp) {
res = result.data || {};
}
return res;
} catch (e) {
res = 'err';
}
}
}
module.exports = Jwt;
解析
generateToken
jwt.sign(payload, secretOrPrivateKey, [options, callback]);
payload ==> 代指要存進(jìn)的內(nèi)容
secretOrPrivateKey ==> 秘鑰畸冲,我這里使用的是生成的私鑰加密,也可以使用不規(guī)則字符观腊。
[options, callback] ==> 參數(shù)邑闲,包括支持的算法等等
verifyToken
jwt.verify(token, secretOrPublicKey, [options, callback]);
token ==> sign生成的Token
secretOrPublicKey ==> 使用生成的公鑰解密。
[options, callback] ==> 使用相同的解密方式
具體參數(shù)
可以查看jsonwebtoken在npm上的詳細(xì)解釋
支持的算法
參數(shù)值 | 數(shù)字簽名或MAC算法 |
---|---|
HS256 | 使用SHA-256哈希算法的HMAC |
HS384 | 使用SHA-384哈希算法的HMAC |
HS512 | 使用SHA-512哈希算法的HMAC |
RS256 | 使用SHA-256哈希算法的RSASSA-PKCS1-v1_5 |
RS384 | 使用SHA-384哈希算法的RSASSA-PKCS1-v1_5 |
RS512 | 使用SHA-512哈希算法的RSASSA-PKCS1-v1_5 |
PS256 | 使用SHA-256哈希算法的RSASSA-PSS(only node ^ 6.12.0 OR> = 8.0.0) |
PS384 | 使用SHA-384哈希算法的RSASSA-PSS(only node ^ 6.12.0 OR> = 8.0.0) |
PS512 | 使用SHA-512哈希算法的RSASSA-PSS(only node ^ 6.12.0 OR> = 8.0.0) |
ES256 | 使用P-256曲線和SHA-256哈希算法的ECDSA |
ES384 | 使用P-384曲線和SHA-384哈希算法的ECDSA |
ES512 | 使用P-521曲線和SHA-512哈希算法的ECDSA |
none | 不包含數(shù)字簽名或MAC值 |
前端的實(shí)際操作方法
怎么存儲(chǔ)
因?yàn)槲冶容^喜歡使用Cookie來存儲(chǔ)的梧油,所以以Cookie為主苫耸。
封裝方法
首先使用一個(gè)npm包,js-cookie儡陨。
npm install js-cookie -S
在合適的文件夾中創(chuàng)建一個(gè)js文件褪子。一般推薦在utils文件夾下
import Cookies from 'js-cookie'
const TokenName = 'XXXXXXXX'
export function getToken() {
return Cookies.get(TokenName)
}
export function setToken(token) {
return Cookies.set(TokenName, token, {
expires: 1,
path: '/'
})
}
export function removeToken() {
return Cookies.remove(TokenName)
}
請(qǐng)求封裝
以VUE來說,按照我之前關(guān)于Axios的文章骗村,封裝請(qǐng)求即可嫌褪。