面試必備-深入理解Java jwt

一、 什麼是JSON Web Token?

JSON Web Token(JWT)是一個開放式標準(RFC 7519),它定義了一種緊湊且自包含的方式,用於在各方之間以JSON對象安全傳輸信息。這些信息可以通過數字簽名進行驗證和信任。可以使用加密(使用HMAC算法)或使用RSA的公鑰/私鑰對對JWT進行簽名。

二、 為什麼使用JWT?

現在都流程微服務架構,到處都是 分佈式,通過session管理用戶登錄狀態成本越來越高,因此慢慢發展成為token的方式做登錄身份校驗,然後通過token去取redis中的緩存的用戶信息,隨著之後jwt的出現,校驗方式更加簡單便捷化,無需通過redis緩存,而是直接根據token取出保存的用戶信息,以及對token可用性校驗,單點登錄更為簡單。

三、 JWT的構成

JWT是由三部分構成(用.分隔),將這三段信息文本用鏈接構成了JWT字符串。就像這樣

xxxxx.yyyyy.zzzzz

第一部分:頭部(header)

第二部分:載荷(payload,該token裡攜帶的有效信息。比如用戶id、名字、年齡等等)

第三部分:簽名(signature)

1. header

JWT的頭部承載的兩部分信息:

{

'typ':'JWT', //聲明類型,這裡是jwt

'alg':'HS256' //聲明加密的算法,通常直接使用HMAC SHA256或RSA

}

Header部分的JSON被Base64Url編碼,形成JWT的第一部分。

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

2. plyload

這裡放聲明內容,可以說就是存放溝通訊息的地方,在定義上有3種聲明(Claims):

Registered claims(註冊聲明):

這些是一組預先定義的聲明,它們不是強制性的,但推薦使用,以提供一組有用的,可互操作的聲明。 其中一些是:iss(發行者),exp(到期時間),sub(主題),aud(受眾)等。

Public claims(公開聲明):

這些可以由使用JWT的人員隨意定義。 但為避免衝突,應在IANA JSON Web令牌註冊表中定義它們,或將其定義為包含防衝突命名空間的URI。

Private claims(私有聲明):

這些是為了同意使用它們但是既沒有登記,也沒有公開聲明的各方之間共享信息,而創建的定製聲明。

示例(這裡存放的即使一個用戶的信息,沒有到期時間、主題之類的聲明):

{

"sub": "1234567890",

"name": "Demo",

"admin": true

}

Playload部分的JSON被Base64Url編碼,形成JWT的第二部分。

請注意,對於已簽名的令牌,此信息儘管受到篡改保護,但任何人都可以閱讀。 除非加密,否則不要將秘密信息放在JWT的有效內容或標題元素中。第二部分不要放置敏感數據如銀行卡帳號、身份證號等信息。一般存放用戶ID、名字、是否管理員、擁有的權限等信息。

3. Signature

第三部分signature用來驗證發送請求者身份,由前兩部分加密形成。

要創建簽名部分,您必須採用編碼標頭,編碼有效載荷,秘鑰,標頭中指定的算法並簽名。

如果你想使用HMAC SHA256算法,簽名將按照以下方式創建:

HMACSHA256(

base64UrlEncode(header) + "." +

base64UrlEncode(payload) + "." +

secret)

此secret存在於你的服務器端,打死都不要告訴任何人,否則就洩密了。

JWTs作為OAuth2.0關於Access_Token的具體解決方案, 為RFC 7519提出,但是後面又有個RFC 6750定義了Bearer Token,就是設置請求頭:

Authorization: Bearer <token>。/<token>

四、 JWT 的使用方式

1. 客戶端用戶發登錄請求。

2. 服務端驗證用戶名密碼。

3. 驗證成功服務端生成一個token,響應給客戶端。

4. 客戶端之後的每次請求header中都帶上這個token,一般放在HTTP 請求的頭信息Authorization字段裡面。

5. 服務端對需要認證的接口要驗證token,驗證成功接收請求。

五、 JWT的優點

體積小,因而傳輸速度更快多樣化的傳輸方式,可以通過URL傳輸、POST傳輸、請求頭Header傳輸(常用)簡單方便,服務端拿到jwt後無需再次查詢數據庫校驗token可用性,也無需進行redis緩存校驗在分佈式系統中,很好地解決了單點登錄問題很方便的解決了跨域授權問題,因為跨域無法共享cookie。

六、 JWT的缺點

因為JWT是無狀態的,因此服務端無法控制已經生成的Token失效,是不可控的,這一點對於是否使用jwt是需要重點考量的獲取到jwt也就擁有了登錄權限,因此jwt是不可洩露的,網站最好使用https,防止中間攻擊偷取jwt在退出登錄 / 修改密碼時怎樣實現JWT Token失效。

面試必備-深入理解Java jwt

七、 Jwt + redis

1. 為什麼使用redis

採用jsonwebtoken生成token時可以指定token的有效期,並且jsonwebtoken的verify方法也提供了選項來更新token的有效期,但這裡使用了express_jwt中間件,express_jwt不提供方法來刷新token。

2. 使用方式:

1. 客戶端請求登錄成功,生成token。

2. 將此token保存在redis中,設置redis的有效期(例如1h)。

3. 新的請求過來,先express_jwt驗證token,驗證成功, 再驗證token是否在redis中存在,存在說明有效。

4. 有效期內客戶端新的請求過來,提取token,更新此token在redis中的有效期。

5. 客戶端退出登錄請求,刪除redis中此token。


分享到:


相關文章: