JWT 筆記
當使用一個API時,其中一個挑戰(zhàn)就是認證(authentication)盟榴。在傳統(tǒng)的web應(yīng)用中,服務(wù)端成功的返回一個響應(yīng)(response)依賴于兩件事。一是吨掌,他通過一種存儲機制保存了會話信息(Session)斩个。每一個會話都有它獨特的信息(id)胯杭,常常是一個長的,隨機化的字符串受啥,它被用來讓未來的請求(Request)檢索信息做个。其次,包含在響應(yīng)頭(Header)里面的信息使客戶端保存了一個Cookie滚局。服務(wù)器自動的在每個子請求里面加上了會話ID居暖,這使得服務(wù)器可以通過檢索Session中的信息來辨別用戶。這就是傳統(tǒng)的web應(yīng)用逃避HTTP面向無連接的方法藤肢。
Token
不是在每一次請求時提供用戶名和密碼的憑證太闺。我們可以讓用戶通過token交換憑證(we can allow the client to exchange valid credentials for a token),這個token提供用戶訪問服務(wù)器的權(quán)限嘁圈。Token通常比密碼更加長而且復雜省骂。比如說,JWTs通常會應(yīng)對長達150個字符丑孩。一旦獲得了token冀宴,在每次調(diào)用API的時候都要附加上它。然后温学,這仍然比直接發(fā)送賬戶和密碼更加安全略贮,哪怕是HTTPS。
把token想象成一個安全的護照仗岖。你在一個安全的前臺驗證你的身份(通過你的用戶名和密碼)逃延,如果你成功驗證了自己,你就可以取得這個轧拄。當你走進大樓的時候(試圖從調(diào)用API獲取資源)揽祥,你會被要求驗證你的護照,而不是在前臺重新驗證檩电。
什么是 JWT 拄丰?
JWT -- JSON Web Token府树,它是基于 RFC 7519 所定義的一種在各個系統(tǒng)中傳遞緊湊和自包含的 JSON 數(shù)據(jù)形式。
- 緊湊(Compact) :由于傳送的數(shù)據(jù)小料按,JWT 可以通過GET奄侠、POST 和 放在 HTTP 的 header 中,同時也是因為小也能傳送的更快载矿。
- 自包含(self-contained) : Payload 中能夠包含用戶的信息垄潮,避免數(shù)據(jù)庫的查詢。
JSON Web Token 由三部分組成使用 . 分割開:
- Header
- Payload
- Signature
一個 JWT 形式上類似于下面的樣子:
xxxxx.yyyy.zzzz
Header 一般由兩個部分組成:
- alg
- typ
alg 是指所使用的 hash 算法,例如 HMAC SHA256 或 RSA闷盔,typ 是 Token 的類型弯洗。
{
"alg": "HS256",
"typ": "JWT"
}
然后使用 Base64Url 編碼成第一部分。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.<second part>.<third part>
Payload
這一部分是 JWT 主要的信息存儲部分逢勾,其中包含了許多種的聲明(claims)牡整。
Claims 的實體一般包含用戶和一些元數(shù)據(jù),這些 claims 分成三種類型:reserved, public, 和 private claims溺拱。
-
(保留聲明)reserved claims :預定義的 一些聲明果正,并不是強制的但是推薦。它們包括:
- iss (issuer) 該JWT的簽發(fā)者
- exp (expiration time) 什么時候過期盟迟,這里是一個Unix時間戳
- sub (subject) 該JWT所面向的用戶
- aud(audience) 接收該JWT的一方
- iat(issued at): 在什么時候簽發(fā)的
- 這里都使用三個字母的原因是保證 JWT 的緊湊
(公有聲明)public claims : 這個部分可以隨便定義,但是要注意和 IANA JSON Web Token 沖突潦闲。
(私有聲明)private claims : 這個部分是共享被認定信息中自定義部分攒菠。
一個 Pyload 可以是這樣子的:
{
"iss": "joe",
"exp": 1300819380,
"sub": "1234567890",
"name": "John Doe",
"admin": true
"iat": 1441593502,
"aud": "www.example.com",
"from_user": "B",
"target_user": "A"
}
這部分同樣使用 Base64Url 編碼成第二部分。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.<third part>
Signature
在創(chuàng)建該部分時候你應(yīng)該已經(jīng)有了 編碼后的 Header 和 Payload 還需要一個秘鑰歉闰,這個加密的算法應(yīng)該 Header 中指定辖众。
一個使用 HMAC SHA256 的例子如下:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
這個 signature 是用來驗證發(fā)送者的 JWT 的同時也能確保在期間不被篡改。
所以和敬,最后你的一個完整的 JWT 應(yīng)該是如下形式:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
注意?被 . 分割開的三個部分