OAuth協議中說到的AccessToken能夠是如下兩種:html
1.任意只起到標識做用的字符串:這種狀況下Resource Server處理請求時須要去找Authorization Server獲取用戶信息。算法
2.攜帶用戶基本信息的加密字符串:這種狀況下Resource Server處理請求時只需解析AccessToken,直接獲取到用戶信息便可。緩存
JWT就是用來生成第二種access token的一種協議。具體介紹:JWT安全
具體來講,一個JWT token就是以下一串字符串:服務器
這個字符串由3部分(Header, Payload, Signature)組成,用"."分隔。編碼
Header加密
這一部分時用來定義構造JWT的參數信息,用一個JSON對象表示以下:spa
{ "alg": "HS256",//定義JWT中的Signature所用的算法 "typ": "JWT"//表示Token的類型,此處統一寫成JWT }
將上述JSON對象的字符串形式進行Base64Url編碼以後就獲得了token中的header部分。code
Payloadserver
這一部分是存儲業務信息的地方。信息也以JSON對象的方式表示:
{ "iss": "Jensen",//簽發人 "exp": "1308726283"//token過時時間戳 }
對象中的key其實能夠爲任意字符串。可是爲了讓token字符串儘量小。key儘可能統一爲3各字符。而後爲了將一些經常使用的key標準化,JWT定義了以下標準key:
iss (issuer):簽發人
exp (expiration time):過時時間
sub (subject):主題
aud (audience):受衆
nbf (Not Before):生效時間
iat (Issued At):簽發時間
jti (JWT ID):編號
詳見 RFC7519
固然咱們也能夠定義本身的key,好比:name:姓名,admin:是否爲admin...
將上述JSON對象的字符串形式進行Base64Url編碼以後就獲得了token中的payload部分。
Signature
將header和payload部分的base64字符串用特定的密鑰進行hash獲得簽名部分。好比咱們選用HMAC SHA256
做爲簽名算法,則簽名過程以下:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
secret
只有服務器端才知道,經過簽名能夠防止token被修改。
與OAuth驗證結合
採用這種方式生成的access token, Resouce Server處理請求的時候(access token能夠放在Authorization Header中,好比:Bearer xxxx)能夠直接解析。可是這裏有兩個問題:1. Authorization Server和Resource Server如何共享簽名的secret?最簡單的方法就是Resource Server和Authorization Server使用統一的secret。可是這樣的話若是有不少Resource Server(好比不一樣的資源提供者)共用一個AuthorizationServer的話可能就有安全問題,這種狀況下就須要針對不一樣的resource server使用不一樣的secret進行簽名了。同時client在申請token的時候也須要告知要訪問那個resource server。2. Token的失效問題由於Token是在Resource Server直接解析,意味着一旦簽發,在其到期前一直有效。用戶logout後也沒辦法將已經產生的token設置爲無效。要解決這個問題,仍是須要Resource Server將access token提交至Authorization Server驗證。Authorization Server能夠將access token進行緩存或者緩存採用相關算法爲其生成的key(好比用簽名做爲key),驗證時只需驗證key是否存在便可。(固然,咱們我進行失效處理時能夠把緩存的key刪掉便可)