JSON Web Token (JWT) 提供一種方法,可在 client 跟 server 之間使用,client 儲存的 JWT,可傳送到 server 進行身份驗證。因為 JWT 是以 base64 編碼原始資料,故 JWT 裡面儲存的資料,並不適合存放真實的使用者相關資料,而是要存放一份可讓 client 存取 server 資源的 token,JWT 透過內建的憑證簽章機制,驗證 JWT 是否有被竄改。
JWT 內容
JWT 就是一個單純的字串,內容有三個部分,header, payload, signature,三個部分用 .
句號連接起來。
Header
{"typ":"JWT","alg":"HS256"}
有兩個欄位
typ
是用 MIME type 定義的 "JWT" 說明這是一個 Json Web Token
alg
簽章演算法,在 JWT 列出來有這些演算法
HS256, HS384, HS512
PS256, PS384, PS512
RS256, RS384, RS512
ES256, ES256K, ES384, ES512
EdDSA
以 base64 編碼後得到
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Payload
除了一些標準定義的欄位外,也可以放自訂的欄位
{"sub":"1234567890","name":"John Doe","iat":1516239022}
iss
issuer
核發此 JWT 的單位
sub
subject
此 JWT 使用的目標對象
aud
audience
誰會使用這個 JWT
exp
expiration
JWT 逾時時間,定義為 UNIX timestamp 數字
nbf
Not Before
JWT 啟用時間,定義為 UNIX timestamp 數字
jat
Issued At
核發此 JWT 的時間 timestamp
jti
JWT ID
unique identifier for the JWT
用 base64 編碼
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
Signature
把前兩個部分合併在一起
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
然後用 HS256 簽章
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
"your-secret"
)
再把三個部分合併成 JWT
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SARsBE5x_ua2ye823r2zKpQNaew3Daq8riKz5A4h3o4
HS256 裡面的密碼,是存放在 server,故可讓 server 驗證此 JWT 是否正確,沒有被竄改。
傳送/存放 JWT
Cookie
可直接透過 Cookie 方式,傳給 client。但設定時,必須加上 HttpOnly,防止 Cookie 被 javascript 讀取,避免遇到 XSS 攻擊
Set-Cookie: jwt=xxx; HttpOnly; max-age=....
接下來每次 request 都會夾帶 jwt cookie 到 server 進行驗證
Sesssion
存放在 Server 的 Session Store 裡面。
JWT 的規格,就是為了把 access token 發送給 client 存放,並在後續的溝通中,使用 JWT 進行身份驗證。透過 JWT,也可以實現 stateless 的 Server。
References
JSON Web Token (JWT) draft-ietf-oauth-json-web-token-32
沒有留言:
張貼留言