Shiro+JWT 實現許可權管理(二)--JWT
目錄
基於cookie-session的認證
基於cookie-session身份驗證機制的過程
cookie-session認證的缺陷
基於jwt的鑑權機制
JWT格式
Header
playload
signature
上篇文章提及到了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: *
。
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了。