JSON Web Token(JWT)機制 git
JWT是一種緊湊且自包含的,用於在多方傳遞JSON對象的技術。傳遞的數據可使用數字簽名增長其安全行。可使用HMAC加密算法或RSA公鑰/私鑰加密方式。程序員
緊湊:數據小,能夠經過URL,POST參數,請求頭髮送。且數據小表明傳輸速度快。github
自包含:使用payload數據塊記錄用戶必要且不隱私的數據,能夠有效的減小數據庫訪問次數,提升代碼性能。web
JWT通常用於處理用戶身份驗證或數據信息交換。算法
用戶身份驗證:一旦用戶登陸,每一個後續請求都將包含JWT,容許用戶訪問該令牌容許的路由,服務和資源。單點登陸是當今普遍使用JWT的一項功能,由於它的開銷很小,而且可以輕鬆地跨不一樣域使用。數據庫
數據信息交換:JWT是一種很是方便的多方傳遞數據的載體,由於其可使用數據簽名來保證數據的有效性和安全性。跨域
官網: jwt.io瀏覽器
1 JWT數據結構安全
JWT的數據結構是 : A.B.C。 由字符點‘.’來分隔三部分數據。服務器
A - header 頭信息
B - payload (有效荷載?)
C - Signature 簽名
1.1 header
數據結構: {「alg」: 「加密算法名稱」, 「typ」 : 「JWT」}
alg是加密算法定義內容,如:HMAC SHA256 或 RSA
typ是token類型,這裏固定爲JWT。
1.2 payload
在payload數據塊中通常用於記錄實體(一般爲用戶信息)或其餘數據的。主要分爲三個部分,分別是:已註冊信息(registered claims),公開數據(public claims),私有數據(private claims)。
payload中經常使用信息有:iss(發行者),exp(到期時間),sub(主題),aud(受衆)等。前面列舉的都是已註冊信息。
公開數據部分通常都會在JWT註冊表中增長定義。避免和已註冊信息衝突。
公開數據和私有數據能夠由程序員任意定義。
注意:即便JWT有簽名加密機制,可是payload內容都是明文記錄,除非記錄的是加密數據,不然不排除泄露隱私數據的可能。不推薦在payload中記錄任何敏感數據。
1.3 Signature
簽名信息。這是一個由開發者提供的信息。是服務器驗證的傳遞的數據是否有效安全的標準。在生成JWT最終數據的以前。先使用header中定義的加密算法,將header和payload進行加密,並使用點進行鏈接。如:加密後的head.加密後的payload。再使用相同的加密算法,對加密後的數據和簽名信息進行加密。獲得最終結果。
2 JWT執行流程
基於JWT機制的單點登陸
1 實現
詳見代碼:https://github.com/yucong/sso/tree/master/sso-jwt
2 注意
使用JWT實現單點登陸時,須要注意token時效性。token是保存在客戶端的令牌數據,若是永久有效,則有被劫持的可能。token在設計的時候,能夠考慮一次性有效或一段時間內有效。若是設置有效時長,則須要考慮是否須要刷新token有效期問題。
3 token保存位置
使用JWT技術生成的token,客戶端在保存的時候能夠考慮cookie或localStorage。cookie保存方式,能夠實現跨域傳遞數據。localStorage是域私有的本地存儲,沒法實現跨域。
4 webstorage
webstorage可保存的數據容量爲5M。且只能存儲字符串數據。
webstorage分爲localStorage和sessionStorage。
localStorage的生命週期是永久的,關閉頁面或瀏覽器以後localStorage中的數據也不會消失。localStorage除非主動刪除數據,不然數據永遠不會消失。
sessionStorage是會話相關的本地存儲單元,生命週期是在僅在當前會話下有效。sessionStorage引入了一個「瀏覽器窗口」的概念,sessionStorage是在同源的窗口中始終存在的數據。只要這個瀏覽器窗口沒有關閉,即便刷新頁面或者進入同源另外一個頁面,數據依然存在。可是sessionStorage在關閉了瀏覽器窗口後就會被銷燬。同時獨立的打開同一個窗口同一個頁面,sessionStorage也是不同的。
補充一下:多設備登陸是徹底沒有問題的,若是項目需求是隻容許單設備登陸,那麼該如何處理了?仍是須要服務端記住客戶端的登陸狀態,很尷尬,有沒有好的方式,既使用JWT作token驗證,也能作單設備登陸,甚至要求更高點:移動端只容許一臺設備登陸,PC端也只容許一臺設備登陸。
感受這個時候,用JWT就不合適了,仍是老老實實用Redis存Token吧。