什么是JWT
Json web token (JWT), 是為了在網(wǎng)絡(luò)應(yīng)用環(huán)境間傳遞聲明而執(zhí)行的一種基于JSON的開(kāi)放標(biāo)準(zhǔn)((RFC 7519).該token被設(shè)計(jì)為緊湊且安全的,特別適用于分布式站點(diǎn)的單點(diǎn)登錄(SSO)場(chǎng)景。
JWT的聲明一般被用來(lái)在身份提供者和服務(wù)提供者間傳遞被認(rèn)證的用戶身份信息,以便于從資源服務(wù)器獲取資源,也可以增加一些額外的其它業(yè)務(wù)邏輯所必須的聲明信息,該token也可直接被用于認(rèn)證,也可被加密。
基于session認(rèn)證的問(wèn)題
http協(xié)議是一種無(wú)狀態(tài)協(xié)議,客戶端和服務(wù)器端進(jìn)行認(rèn)證請(qǐng)求時(shí)需要用戶名密碼,我們并不知道時(shí)哪個(gè)用戶發(fā)出的請(qǐng)求,為了識(shí)別時(shí)誰(shuí)請(qǐng)求的,就要再服務(wù)器端存儲(chǔ)一份登陸信息,同時(shí)會(huì)傳遞給瀏覽器,告訴其保存為cookie,
這種傳統(tǒng)的session認(rèn)證暴露出一些問(wèn)題,用戶越多,服務(wù)器端開(kāi)銷越大,擴(kuò)展不好,容易被csrf攻擊
基于token的授權(quán)機(jī)制
基于token的授權(quán)機(jī)制不需要服務(wù)器端保留用戶信息,即不需要知道用戶在那臺(tái)服務(wù)器登陸了。
下圖是jwt再小程序的應(yīng)用:

登陸之后每次請(qǐng)求都會(huì)在header里帶上token。
JWT協(xié)議
JWT有三段信息組成如下
eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJvZVhQMTVVWmJHcllreWhSQkhyWnFuNXFKSDM4IiwiY3JlYXRlZCI6MTU0MDgwNjI2NzUxMiwiZXhwIjoxNTQxNDExMDY3LCJrZXkiOiI3b2xOM05QVWlpeHNVWDdIYmdZZmh3PT0ifQ.nxvr_Na0fya9O2fC1rsbghicAU1be6n5fHTP4BdNEKGjyfmi3Z9NZMmlU4rHv5O5bOWWM5vf_-cKskG63dYVVg
JWT構(gòu)成
有三部分組成:頭部(header)、載荷(payload)、簽名(signature)
header:
JWT的header聲明了2部分信息,類型和加密算法,
{
'typ':'JWT',
'alg':'HS256'
}
將其base64加密得到
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
payload:
存放有效信息的地方,包含三個(gè)部分:
1、標(biāo)準(zhǔn)中注冊(cè)的聲明
iss: jwt簽發(fā)者
sub: jwt所面向的用戶
aud: 接收jwt的一方
exp: jwt的過(guò)期時(shí)間,這個(gè)過(guò)期時(shí)間必須要大于簽發(fā)時(shí)間
nbf: 定義在什么時(shí)間之前,該jwt都是不可用的.
iat: jwt的簽發(fā)時(shí)間
jti: jwt的唯一身份標(biāo)識(shí),主要用來(lái)作為一次性token,從而回避重放攻擊。
定義個(gè)簡(jiǎn)單的payload
{
"sub": "1234567890",
"name": "test",
}
base64加密結(jié)果: eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9
2、公共的聲明
信息隨便填,但不建議放敏感信息,可在客戶端解密
3、私有的聲明
提供者和消費(fèi)者所共同定義的聲明,一般不建議存放敏感信息,因?yàn)閎ase64是對(duì)稱解密的,意味著該部分信息可以歸類為明文信息。
signature:
簽名信息有三部分組成
1、 header(base64后) 這個(gè)部分需要base64加密后的header和base64加密后的payload使用.連接組成的字符串,然后通過(guò)header中聲明的加密方式進(jìn)行加鹽secret組合加密,然后就構(gòu)成了jwt的第三部分。
2、payload(base64后)
3、secret 保存在服務(wù)器端
var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);
var signature = HMACSHA256(encodedString, 'secret');
// TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
注意事項(xiàng):
secret是保存在服務(wù)器端的,jwt的簽發(fā)生成也是在服務(wù)器端的,secret就是用來(lái)進(jìn)行jwt的簽發(fā)和jwt的驗(yàn)證,所以,它就是你服務(wù)端的私鑰,在任何場(chǎng)景都不應(yīng)該流露出去。一旦客戶端得知這個(gè)secret, 那就意味著客戶端是可以自我簽發(fā)jwt了
安全相關(guān)
- 不應(yīng)該在payload里放敏感信息
- 保護(hù)好secret
- 使用https\