Json web token (JWT), 是爲了在網絡應用環境間傳遞聲明而執行的一種基於JSON的開放標準((RFC 7519).該token被設計爲緊湊且安全的,特別適用於分佈式站點的單點登陸(SSO)場景。JWT的聲明通常被用來在身份提供者和服務提供者間傳遞被認證的用戶身份信息,以便於從資源服務器獲取資源,也能夠增長一些額外的其它業務邏輯所必須的聲明信息,該token也可直接被用於認證,也可被加密。web
基於session認證所顯露的問題
Session: 每一個用戶通過咱們的應用認證以後,咱們的應用都要在服務端作一次記錄,以方便用戶下次請求的鑑別,一般而言session都是保存在內存中,而隨着認證用戶的增多,服務端的開銷會明顯增大。算法
擴展性: 用戶認證以後,服務端作認證記錄,若是認證的記錄被保存在內存中的話,這意味着用戶下次請求還必需要請求在這臺服務器上,這樣才能拿到受權的資源,這樣在分佈式的應用上,相應的限制了負載均衡器的能力。這也意味着限制了應用的擴展能力。json
CSRF: 由於是基於cookie來進行用戶識別的, cookie若是被截獲,用戶就會很容易受到跨站請求僞造的攻擊。安全
JWT的構成
第一部分咱們稱它爲頭部(header),第二部分咱們稱其爲載荷(payload, 相似於飛機上承載的物品),第三部分是簽證(signature).服務器
header
jwt的頭部承載兩部分信息:cookie
聲明類型,這裏是jwt
聲明加密的算法 一般直接使用 HMAC SHA256
完整的頭部就像下面這樣的JSON:網絡
{
'typ': 'JWT',
'alg': 'HS256'
}
而後將頭部進行base64加密(該加密是能夠對稱解密的),構成了第一部分.session
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
payload
載荷就是存放有效信息的地方。這個名字像是特指飛機上承載的貨品,這些有效信息包含三個部分負載均衡
標準中註冊的聲明
公共的聲明
私有的聲明
標準中註冊的聲明 (建議但不強制使用) :分佈式
iss: jwt簽發者
sub: jwt所面向的用戶
aud: 接收jwt的一方
exp: jwt的過時時間,這個過時時間必需要大於簽發時間
nbf: 定義在什麼時間以前,該jwt都是不可用的.
iat: jwt的簽發時間
jti: jwt的惟一身份標識,主要用來做爲一次性token,從而回避重放攻擊。
signature
JWT的第三部分是一個簽證信息,這個簽證信息由三部分組成:
header (base64後的)
payload (base64後的)
secret
這個部分須要base64加密後的header和base64加密後的payload使用.鏈接組成的字符串,而後經過header中聲明的加密方式進行加鹽secret組合加密,而後就構成了jwt的第三部分。
將這三部分用.鏈接成一個完整的字符串,構成了最終的jwt
secret是保存在服務器端的,jwt的簽發生成也是在服務器端的,secret就是用來進行jwt的簽發和jwt的驗證,因此,它就是你服務端的私鑰,在任何場景都不該該流露出去。一旦客戶端得知這個secret, 那就意味着客戶端是能夠自我簽發jwt了。
優勢由於json的通用性,因此JWT是能夠進行跨語言支持的,像JAVA,JavaScript,NodeJS,PHP等不少語言均可以使用。由於有了payload部分,因此JWT能夠在自身存儲一些其餘業務邏輯所必要的非敏感信息。便於傳輸,jwt的構成很是簡單,字節佔用很小,因此它是很是便於傳輸的。它不須要在服務端保存會話信息, 因此它易於應用的擴展安全相關不該該在jwt的payload部分存放敏感信息,由於該部分是客戶端可解密的部分。保護好secret私鑰,該私鑰很是重要。若是能夠,請使用https協議