JSON Web Token (JWT)
簡介
JSON Web令牌(JWT)是一個(gè)開放標(biāo)準(zhǔn)(RFC 7519),它定義了一種緊湊且獨(dú)立的方法,用于在各方之間安全地將信息作為JSON對象傳輸。由于此信息是經(jīng)過數(shù)字簽名的,因此可以被驗(yàn)證和信任。
組成部分
JSON Web Token由三個(gè)部分組成,使用(.)分割。
Header
Payload
Signature
因此JWT的格式為:xxxx.yyyy.zzzz
第一部分Header
通常包括兩部分:令牌的類型(即JWT),以及使用的哈希算法(如HMAC SHA256或RSA)。
{"alg": "HS256","typ": "JWT"}
然后,這個(gè)JSON是Base64Url編碼形成JWT的第一部分。
第二部分Payload
通常包括claims, claims是關(guān)于實(shí)體(通常是用戶)和附加元數(shù)據(jù)的聲明。
這里有三個(gè)類型的聲明:
reserved
public
private
Reserved claims
這些是一組預(yù)定義的聲明,不是強(qiáng)制性的,而是建議的,以提供一組有用的,可互操作的聲明。其中有些是:
iss?(issuer)
exp?(expiration time)
sub?(subject)
aud?(audience)
其他
PS:請注意,聲明名稱只有三個(gè)字符,因?yàn)镴WT意味著緊湊。
Public claims
這些可以由使用JWT的人隨意定義。但為避免沖突,應(yīng)在
IANA JSON Web Token注冊表
https://www.iana.org/assignments/jwt/jwt.xhtml中定義它們,或者將其定義為包含防沖突命名空間的URI。
Private claims
這些是為共享使用它們的各方之間共享信息而創(chuàng)建的自定義聲明。
例如
{"sub": "1234567890","name": "John Doe","admin": true}
該payload被Base64Url編碼以形成JSON Web令牌的第二部分。
第三部分Signature
創(chuàng)建簽名部分,必須使用以下3個(gè)數(shù)據(jù)根據(jù)header中指定的算法, 并簽名用于驗(yàn)簽。
base64編碼的header
編碼的payload
一個(gè)secret
例如:如果要使用HMAC SHA256算法,將以以下方式創(chuàng)建簽名:
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
最后拼接起來
輸出是三個(gè)由點(diǎn)(.)分隔的Base64-URL字符串,可以在HTML和HTTP環(huán)境中輕松傳遞這些字符串,與基于XML的標(biāo)準(zhǔn)(例如SAML)相比,它更緊湊。
下面這個(gè)就是編碼簽名后的JWT結(jié)果字符串:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c.
可以使用JWT Debug 工具測試簽名和驗(yàn)簽名。
https://jwt.io/#debugger-io如何使用JWT
獲取JWT并將其用于訪問API或資源:
客戶端從授權(quán)服務(wù)器登錄
登錄成功后授權(quán)服務(wù)器下發(fā)JWT令牌返回給客戶端
客戶端使用JWT令牌訪問受保護(hù)的API資源服務(wù)器
請注意,使用簽名的令牌,令牌中包含的所有信息都會(huì)暴露給用戶或其他方(因使用的是Base64可以反編譯獲得原文),即使他們無法更改其中的數(shù)據(jù),但不應(yīng)將機(jī)密信息放入令牌中,由于缺乏安全性,不應(yīng)該將敏感的會(huì)話數(shù)據(jù)存儲(chǔ)在瀏覽器中。
在身份驗(yàn)證中,當(dāng)用戶使用其憑據(jù)成功登錄時(shí),將返回JSON Web Token。由于令牌是憑據(jù),因此必須格外小心以防止安全問題。通常,令牌的保留時(shí)間不應(yīng)超過要求的時(shí)間。
每當(dāng)用戶想要訪問受保護(hù)的路由或資源時(shí),用戶代理應(yīng)發(fā)送JWT,通常在使用Bearer模式的Authorization header中。
header的內(nèi)容應(yīng)如下所示:?Authorization: Bearer
在某些情況下,這可以是無狀態(tài)授權(quán)機(jī)制。服務(wù)器的受保護(hù)路由將在header中檢查有效的JWT,如果存在,則將允許用戶訪問受保護(hù)的資源。如果JWT包含必要的數(shù)據(jù),則可以減少查詢數(shù)據(jù)庫中某些操作的需求,盡管并非總是如此。
如果令牌是在header中發(fā)送的,則跨域資源共享(CORS)不會(huì)成為問題,因?yàn)樗皇褂胏ookie。
總結(jié)
JSON Web Token(簡稱JWT)使用點(diǎn)(.)分隔三個(gè)Base64加密部分拼接在一起的字符串。
優(yōu)點(diǎn)
輕量跨語言,使用字符串傳輸,不同開發(fā)語言系統(tǒng)都能使用
無狀態(tài),無需消耗緩存或其他數(shù)據(jù)存儲(chǔ)保存狀態(tài)
可跨域
可承載數(shù)據(jù)傳輸?shù)讲煌到y(tǒng),減少數(shù)據(jù)庫的訪問
可設(shè)置有效時(shí)間,在網(wǎng)關(guān)層/入口攔截器處理判斷
簽名和承載數(shù)據(jù)不可更改
缺點(diǎn)
承載數(shù)據(jù)完全暴露
無狀態(tài),不能有效管理token,需要等有效時(shí)間失效
有效時(shí)間續(xù)期問題
擴(kuò)展
現(xiàn)在開發(fā)的系統(tǒng)是生成一個(gè)token(如UUID字符串),保存在緩存中,由服務(wù)器管理,校驗(yàn)和存儲(chǔ)需要一些資源,當(dāng)大量請求的時(shí)候后端會(huì)有一些壓力。
因此參考了JWT的特性,把token字符串改為JWT的形式,token放在緩存,token狀態(tài)因業(yè)務(wù)問題還是需要保留。這樣的好處是保持業(yè)務(wù)不變,利用JWT的承載數(shù)據(jù)校驗(yàn)有效時(shí)間和身份等判斷,減少與緩存的交互壓力,可以很大程度有效過濾掉無用的token請求(雖然沒了JWT的無狀態(tài)等特性)。
source://winskin.github.io/2020/03/29/2020-03-29-JWT簡介

分享&在看
