JWT

1. 爲何有JWT

服務器端維護登陸狀態,使用傳統Cookie和Session方案,擴展性很差。而JWT可實現服務器無狀態,擴展性好。html

在單點登陸的時候,共享登陸狀態信息的實現有如下兩種方案:前端

  • 方案一:使用session 數據持久化(寫入數據庫或者Redis中),服務受到請求後,向持久層請求數據,但若是持久層掛了,就會單點失敗。
  • 方案二:使用JWT,服務器不保存session數據,全部狀態信息都保存在客戶端,每次請求都發回服務器。

2. JWT是什麼?

JSON Web Token(JWT)是一個開放標準(RFC 7519),它定義了一種緊湊且獨立的方式,用於在各方之間做爲JSON對象安全地傳輸信息。 此信息能夠經過數字簽名進行驗證和信任。 JWT可使用HMAC對稱加密算法或RSA (ECDSA) 非對稱加密算法進行簽名。web

3. 實現原理?

服務器認證之後,生成一個json對象,發回給客戶端。以後,客戶端與服務端通訊,回傳這個JSON對象。服務器靠這個對象認定用戶身份。爲防止用戶篡改數據,服務器生成這個對象的時候,會加上簽名。服務器再也不保存任何session數據,實現了服務無狀態,從而比較容易實現擴展。算法

4. JWT長什麼樣?

Header.Payload.Signature數據庫

  • Header:經Base64URL算法轉成字符串的JSON對象,描述JWT的元數據,如簽名算法(默認HMAC SHA256 對稱加密)、令牌類型等屬性
  • Payload:經Base64URL算法轉成字符串的JSON對象,實際傳輸的數據,如簽發人iss、主題sub、受衆aud、過時時間exp、生效時間nbf、簽發時間iat、編號jti (7個官方字段)以及自定義私有字段
  • Signature:對前兩部分的簽名,指定密鑰secret ,對頭部以及載荷內容進行簽名。若是有人對頭部以及載荷的內容解碼之後進行修改,再進行編碼的話,即時使用相同密鑰簽名,結果也與原來的不同。若是不知道服務器加密時候用的祕鑰的話,得出來的簽名也是不同的。

截取自JWT官網

Base64URL算法json

Base64編碼後的字符串中可能包含 + 、/ 和 = 三個字符,在 URL 裏面有特殊含義,因此要被替換掉:= 被省略、+ 替換成-,/ 替換成 _ 。這就是 Base64URL 算法。api

JWT做爲一個令牌(token),有些場景可能會放到URL(如:api.example.com/?token=xxx),所以須要採用Base64URL 算法將Header 和 Payload 轉化爲字符串。瀏覽器

5.存儲位置?

JWT可選擇的客戶端存儲位置包括sessionStorage、localStorage和cookie。三個位置各有優缺點,具體比較以下。安全

優勢 缺點
sessionStorage 瀏覽器關閉即自動清除數據 存在不可跨瀏覽器窗口共享數據,跨窗口需從新登陸;可被JS讀取,可能受到XSS攻擊
localStorage 可跨窗口共享數據,過時時間前可實現自動登陸 退出登陸或JWT過時需主動清除數據;可被JS讀取,可能受到XSS攻擊
cookie 可設置httpOnly屬性防止被JS讀取,防止XSS攻擊;可設置secure保證JWT只在HTTPS下傳輸 容易受到CSRF攻擊

Token的初衷是防範CSRF攻擊。防範大概的原理是,cookie會被瀏覽器自動帶上,而token 或 JWT須要在發送請求前,前端代碼中去設置請求頭,防範了CSRF的攻擊。XSS攻擊的防範比較容易,所以筆者我的不推薦將JWT存在cookie裏(我的意見,不喜勿碰)。服務器

6.JWT的優勢和缺點

優勢:

  • 全部狀態信息存儲在客戶端,減輕了服務端壓力
  • JWT不只能夠用於認證,也能夠用於交換信息。有效使用JWT,能夠下降服務器查詢數據庫的次數

缺點:

  • 使用過程當中沒法廢止或修改,簽發後到期前始終有效
  • 包含認證信息,泄露後權限被盜用 (針對該問題,建議採用較短的有效期,並使用HTTPS協議傳輸)
  • 續簽問題

7.使用過程當中JWT失效怎麼辦?

若是在用戶使用過程當中,JWT失效(過時時間到了),頁面跳轉至登陸頁,這樣會形成很差的用戶體驗。

  • 解決方案1:Refresh Token。服務器端token過時,通知客戶端,客戶端使用Refresh Token從新申請一個全新的JWT使用。
  • 解決方案2:將過時時間設置爲深夜,好比凌晨三、4點,這樣出現操做中token過時的可能性就極小了。該方案主要針對TO B業務。不過,即便是TO C的業務,凌晨三、4點使用的可能性也較小,真的碰上了登陸一下好像也能夠理解。

關於Token

從範圍來說,JWT屬於Token,Token的形式能夠多種多樣,不限於JWT這種Header.Payload.Signature樣子。JWT的特色大部分都適用於Token,固然Token也有本身的特性,本文(本次討論)沒有詳細討論Token相關內容,感興趣的小夥伴能夠自行發掘。

參考

https://JWT.io/introduction/

http://www.ruanyifeng.com/blo...

http://blog.didispace.com/jso...

相關文章
相關標籤/搜索