Shiro+JWT 實現權限管理(二)--JWT


上篇文章提及到了JWT,以及為什么使用Token,這篇文章就圍繞JWT展開論述吧.

JWT 官方文檔:https://jwt.io/introduction/   大致就是介紹了JWT是啥東西、運用場景 、怎么用..  

 

基於cookie-session的認證

說到JWT,我覺得有必要來談談基於cookie-session的認證

我們都知道,http協議本身是一種無狀態的協議,也就是說用戶向我們的應用提供了用戶名和密碼進行身份認證,在下一次請求時,用戶還需要進行認證才行.因為根據http請求我們無法判斷是哪個用戶發送的請求,所以為了能識別是哪個用戶發出的請求,只能在服務端存儲一份用戶登錄的信息,這些信息在響應時傳遞給瀏覽器,並告訴它保存為cookie,以便下次請求是發送給后端,這樣后端就能識別請求來自哪個用戶.這就是傳統基於cookie-session的認證.

 

基於cookie-session身份驗證機制的過程

             cookie-session認證

  • 用戶輸入登錄信息
  • 服務端驗證登錄信息是否正確,如果正確就在服務器端為這個用戶創建一個 Session,並把 Session 存入數據庫
  • 服務器端會向客戶端返回帶有 sessionID 的 Cookie
  • 客戶端接收到服務器端發來的請求之后,看見響應頭中的 Set-Cookie 字段,將 Cookie 保存起來
  • 接下來的請求中都會帶上這個 Cookie,服務器將 sessionID 和 數據庫中的相匹配,如果有效則處理該請求
  • 如果用戶登出,Session 會在客戶端和服務器端都被銷毀

 

cookie-session認證的缺陷

  • 擴展性不好,當擁有多台服務器的情況下,如何共享 Session 會成為一個問題,也就是說,用戶第一個訪問的時候是服務器 A,而第二個請求被轉發給了服務器 B,那服務器 B 無法得知其狀態。(
  • 安全性不好,攻擊者可以利用本地 Cookie 進行欺騙和 CSRF 攻擊。
  • Session 保存在服務器端,如果短時間內有大量用戶,會影響服務器性能。
  • 跨域問題,Cookie 屬於同源策略限制的內容之一。

 

基於jwt的鑒權機制

               JWT認證

  • 用戶使用用戶名密碼來請求服務器
  • 服務器進行驗證用戶的信息
  • 服務器通過驗證發送給用戶一個token
  • 客戶端存儲token,並在每次請求時附送上這個token值
  • 服務端驗證token值,並返回數據.這個token必須要在每次請求時傳遞給服務端,它應該保存在請求頭里, 另外,服務端要支持CORS(跨來源資源共享)策略,一般我們在服務端這么做就可以了Access-Control-Allow-Origin: *
基於token的鑒權機制類似於http協議,也是無狀態的,它不需要在服務端去保留用戶的認證信息或者會話信息。這就意味着基於token認證機制的應用不需要去考慮用戶在哪一台服務器登錄了,這就為應用的擴展提供了便利。
 

JWT格式 

JWT是由三段信息構成的,將這三段信息文本用.鏈接一起就構成了JWT字符串。就像這樣:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

JWT官網地址:https://jwt.io/   在首頁下部的Debugger部分可以對JWT字符串進行解析(Base64),如下.

Header

頭部含兩部分信息

  • 類型聲明,這里是jwt
  • 聲明加密的算法 常用的是HMAC SHA256

playload

載荷就是存放有效信息的地方。這個名字像是特指飛機上承載的貨品,這些有效信息包含三個部分

  • 標准中注冊的聲明
  • 公共的聲明
  • 私有的聲明

標准中注冊的聲明 (建議但不強制使用) :

  • iss: jwt簽發者
  • sub: jwt所面向的用戶
  • aud: 接收jwt的一方
  • exp: jwt的過期時間,這個過期時間必須要大於簽發時間
  • nbf: 定義在什么時間之前,該jwt都是不可用的.
  • iat: jwt的簽發時間
  • jti: jwt的唯一身份標識,主要用來作為一次性token,從而回避重放攻擊。

公共的聲明
公共的聲明可以添加任何的信息,一般添加用戶的相關信息或其他業務需要的必要信息.但不建議添加敏感信息,因為該部分在客戶端可解密.

私有的聲明
私有聲明是提供者和消費者所共同定義的聲明,一般不建議存放敏感信息,因為base64是對稱解密的,意味着該部分信息可以歸類為明文信息。

signature

jwt的第三部分是一個簽證信息,這個簽證信息由三部分組成:

  • header (base64后的)
  • payload (base64后的)
  • secret

這個部分需要base64加密后的header和base64加密后的payload使用.連接組成的字符串,然后通過header中聲明的加密方式進行加鹽secret組合加密,然后就構成了jwt的第三部分。

注意:secret是保存在服務器端的,jwt的簽發生成也是在服務器端的,secret就是用來進行jwt的簽發和jwt的驗證,所以,它就是你服務端的私鑰,在任何場景都不應該流露出去。一旦客戶端得知這個secret, 那就意味着客戶端是可以自我簽發jwt了。

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM