JWT(json web token)是爲了在網絡應用環境間傳遞聲明而執行的一種基於JSON的開放標準。java
JWT的聲明通常被用來在身份提供者和服務提供者間傳遞被認證的用戶身份信息,以便於從資源服務器獲取資源。好比用在用戶登陸上。web
在傳統的用戶登陸認證中,由於http是無狀態的,因此都是採用session方式。用戶登陸成功,服務端會保證一個session,固然會給客戶端一個sessionId,客戶端會把sessionId保存在cookie中,每次請求都會攜帶這個sessionId。算法
圖片來源於網絡博客json
cookie+session這種模式一般是保存在內存中,並且服務從單服務到多服務會面臨的session共享問題,隨着用戶量的增多,開銷就會越大。而JWT不是這樣的,只須要服務端生成token,客戶端保存這個token,每次請求攜帶這個token,服務端認證解析就可。服務器
圖片來源於網絡博客cookie
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJvcmciOiLku4rml6XlpLTmnaEiLCJuYW1lIjoiRnJlZeeggeWGnCIsImV4cCI6MTUxNDM1NjEwMywiaWF0IjoxNTE0MzU2MDQzLCJhZ2UiOiIyOCJ9.49UF72vSkj-sA4aHHiYN5eoZ9Nb4w5Vb45PsLF7x_NY網絡
第一部分咱們稱它爲頭部(header),第二部分咱們稱其爲載荷(payload),第三部分是簽證(signature)。session
header測試
jwt的頭部承載兩部分信息:加密
聲明類型,這裏是jwt
聲明加密的算法 一般直接使用 HMAC SHA256
完整的頭部就像下面這樣的JSON:
{
"typ": "JWT",
"alg": "HS256"
}
而後將頭部進行base64加密(該加密是能夠對稱解密的),構成了第一部分:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
playload
載荷就是存放有效信息的地方。這個名字像是特指飛機上承載的貨品,這些有效信息包含三個部分
標準中註冊的聲明
公共的聲明
私有的聲明
標準中註冊的聲明 (建議但不強制使用) :
iss: jwt簽發者
sub: jwt所面向的用戶
aud: 接收jwt的一方
exp: jwt的過時時間,這個過時時間必需要大於簽發時間
nbf: 定義在什麼時間以前,該jwt都是不可用的.
iat: jwt的簽發時間
jti: jwt的惟一身份標識,主要用來做爲一次性token,從而回避重放攻擊。
公共的聲明 :
公共的聲明能夠添加任何的信息,通常添加用戶的相關信息或其餘業務須要的必要信息.但不建議添加敏感信息,由於該部分在客戶端可解密.
私有的聲明 :
私有聲明是提供者和消費者所共同定義的聲明,通常不建議存放敏感信息,由於base64是對稱解密的,意味着該部分信息能夠歸類爲明文信息。
定義一個payload:
{
"name":"Free碼農",
"age":"28",
"org":"今日頭條"
}
而後將其進行base64加密,獲得Jwt的第二部分:
eyJvcmciOiLku4rml6XlpLTmnaEiLCJuYW1lIjoiRnJlZeeggeWGnCIsImV4cCI6MTUxNDM1NjEwMywiaWF0IjoxNTE0MzU2MDQzLCJhZ2UiOiIyOCJ9
signature
jwt的第三部分是一個簽證信息,這個簽證信息由三部分組成:
header (base64後的)
payload (base64後的)
secret (這個咱們能夠使用登錄用戶id)
這個部分須要base64加密後的header和base64加密後的payload使用.鏈接組成的字符串,而後經過header中聲明的加密方式進行加鹽secret組合加密,而後就構成了jwt的第三部分:
49UF72vSkj-sA4aHHiYN5eoZ9Nb4w5Vb45PsLF7x_NY
密鑰secret是保存在服務端的,服務端會根據這個密鑰進行生成token和驗證,因此須要保護好。
Maven
<dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.1.0</version></dependency>
加密與校驗代碼:
加密方法與校驗方法
測試代碼:
測試方法
代碼輸出結果:
代碼輸出結果
能夠很清楚的看到,第一次用生成的Token去校驗,校驗經過,而且輸出了Token中包涵的信息。第二次用過時的Token調用校驗方法,直接拋出異常,提示Token信息過時。
一、由於json的通用性,因此JWT是能夠進行跨語言支持的,像JAVA,JavaScript,NodeJS,PHP等不少語言均可以使用。
二、payload部分,JWT能夠在自身存儲一些其餘業務邏輯所必要的非敏感信息。
三、便於傳輸,jwt的構成很是簡單,字節佔用很小,因此它是很是便於傳輸的。它不須要在服務端保存會話信息, 因此它易於應用的擴展