JWT學習文章:
簡介
JWT全拼是JSON Web Tocken,是目前最流行的跨域身份認證解決方案,特別適合分布式系統,減少用戶麻煩,保證賬號安全,減少服務器負載。
有人經常將OAuth與JWT搞混,兩種是用於同一場景的不同情況。同一場景是指登錄場景,不同情況是指,OAuth是第三方授權登錄(詳情戳這里),JWT是直接登錄。
產生的背景
最經典的登錄實現方式是通過session:
1.用戶輸入用戶名、密碼提出登錄請求;
2.服務器收到請求並驗證用戶名和密碼,正確情況下存儲在服務器的session中,並返回用戶session_id;
3.用戶發起新的請求並攜帶cookie中的session_id;
4.服務器驗證session_id並驗證服務器內的session,無誤響應用戶請求;
所有后續請求都如此進行,如果服務器對session有時間限制后自動銷毀,到時間后用戶將重新進行用戶名、密碼的登錄。
存在的問題
如果用戶數量過大,服務器中存儲大量的session信息,嚴重影響服務器的性能;
服務器無法方便的進行分布式部署,因為session不能方便的實現服務器間的同步,無法實現橫向擴展(不是不能實現,而是實現會變得復雜,例如創建session持久化層,此種方法修改難度大,且持久化層掛掉,所有服務都會掛掉)。
應運而生,JWT解決了以上的問題。接下來進行學習JWT的相關知識。
JWT結構
組成部分
Header
Payload
Signature
連接形式
xxxxx.yyyyy.zzzzz
讓我們一步步來說:
Header
格式:JSON
包括內容是:
Token的類型,就是JWT
加密的方式,例如HMAC SHA256 or RSA,一般使用HMAC SHA256
例子:
{ "alg": "HS256", "typ": "JWT" }
接着用Base64Url編碼成為JWT的第一部分。
Payload
存放有效信息的部分,有效信息主要包含三部分:
- 標准中注冊的聲明
- 公共的聲明
- 私有的聲明
標准中注冊的聲明:
iss: JWT簽發者
sub: JWT所面向的用戶
aud: 接收JWT的一方
exp: JWT的過期時間,這個過期時間必須要大於簽發時間
nbf: 定義在什么時間之前,該JWT都是不可用的.
iat: JWT的簽發時間
jti: JWT的唯一身份標識,主要用來作為一次性token,從而回避重放攻擊。
此部分內容建議使用但不強制。
公共聲明:
可以添加任何信息,一般是用戶信息和業務信息。不建議添加敏感信息,因為payload部分會用Base64Url編碼,可能會被反向解密。
私有聲明:
可以存放前后端共同定義的聲明,方便前后端進行不敏感的信息交換。同樣不建議添加敏感信息,原因也是可能會被解碼。
例子:
此部分內容同樣進行Base64Url編碼,組成JWT的第二部分內容。
Signature
此部分內容是Header和Payload各自經過Base64Url編碼后用“.”連接,根據Header中聲明的加密方法進行加密后組成的。
類似下面的方式:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
使用方式
加在http請求或HTTPS的請求頭中,樣式如下:
注意一定要在token之前加上Bearer,之間空格。
結語
掌握JWT的結構和原理是根本。
大家可以生成一個密鑰,在https://JWT.io/#debugger-io上試試,方便進行理解。
此篇文章可以當做JWT的文檔來看,因為結構部分的內容和JWT文檔的內容並無二意。

