JWT登入認證-專案BotBattle

AbstractJava發表於2024-03-19

目錄
  • session 授權認證原理
  • 密碼儲存與加密
  • jwt(JSON Web Token)驗證
    • JWT 的無狀態認證機制
    • 實踐與除錯

實現目標:在沒有判斷登入認證的情況下,訪問任意介面,直接跳轉到登入介面。

新增Spring Security依賴來實現登入認證

session 授權認證原理

實現config.SecurityConfig

SessionID 相當於給瀏覽器頒發的一張臨時身份證,之後瀏覽器在執行業務操作的時候,都要隨身攜帶這個身份證。

1.sessionID 生成與儲存
login 頁面登入成功後,後端生成 SessionID,將其同時儲存在後端資料庫與瀏覽器的 Cookie 中
2.sessionID 和請求一起傳送給後端
每次向後端 Springboot 傳送請求的同時,會從 Cookie 中取出將 SessionID 一起傳送給後端 Springboot。Springboot 透過向資料庫查詢判斷當前 SessionID 是否存在以及是否過期


  • PS:後端查詢判斷
    如果存在,將有關 SessionID 的資訊(包括對應的使用者名稱、過期時間)從資料庫中取出,判斷是否過期。
    若 SessionID 過期或者根本不存在,則返回給使用者登入頁重新登入。
    若 SessionID 沒有過期,則透過 SessionID 與使用者資訊 userInfo 的對映關係,將對應的 User 提取到上下文中(在 Contoller 中就可以透過一些 API 來拿到 User),成功進行授權頁面的訪問。

  • 來源 https://gitee.com/XZHongAN

密碼儲存與加密

config.SecurityConfig類中,實現使用者密碼的加密儲存

放行登入、註冊等介面
如果直接用明文密碼來儲存,需要在資料庫中加上{noop}標記,代表不需要加密直接判斷

  • BCrypt 是 一種用於密碼雜湊的安全演算法。藉助BCryptPasswordEncoderencode()方法更新資料庫中的明文密碼

  • 要在新增階段就直接儲存加密階段的程式碼,用到 PasswordEncoder

jwt(JSON Web Token)驗證

對於前後端分離的情況,使用 session 可能會出現跨域問題。
瀏覽器的同源策略(Same-Origin Policy)限制了來自不同源(即不同的協議、域名或埠)互相之間的某些操作。

想象你住在一個嚴格管理的小區裡(瀏覽器),而小區有一條規定:你只能和住在同一棟樓裡的鄰居(同源伺服器)自由交流和分享東西(資料請求)。現在,你想要和住在隔壁樓的一個鄰居交換東西(跨域請求),但是物業(瀏覽器的同源策略)不允許你這麼做,除非隔壁樓的鄰居明確告訴物業,他們願意接受你,並且確認這次交換是安全的(CORS 策略)。如果你想透過物業的特殊通行證(Cookie)證明你的身份來進行這次交換,物業還需要驗證這個通行證是不是也被鄰居接受的(允許攜帶 Cookie 的跨域請求)。在使用 Session 認證時,如果沒有正確處理這些安全策略,你就無法成功地和不同樓棟的鄰居交換東西了。

比如 Ajax 請求資料。當你的前端應用嘗試從一個源向另一個源的伺服器傳送請求時,就會遇到跨域問題。

JWT 的無狀態認證機制

JWT 的 T 是指包含認證資訊的 Token。這個 Token 是在使用者成功登入後生成的,包含了一系列的宣告(Claims),例如使用者的 ID、Token 的發行者、過期時間等。

這個 Token 會被伺服器數字簽名後傳送給客戶端,客戶端隨後的每個請求都會攜帶這個 Token。

伺服器透過驗證這個 Token 的簽名來認證使用者的請求,而不需要儲存任何使用者狀態資訊。伺服器不需要儲存任何使用者狀態資訊,也就是“無狀態的認證機制”的“無狀態”。


jwt 驗證的優點

  • 容易實現跨域
  • 不需要在伺服器端儲存
  • 對於有多個伺服器的情況,就可以實現用一個令牌來登入多個伺服器

新增依賴:

jjwt-api
jjwt-impl
jjwt-jackson

對於 url 可以分為兩大類:

  • 公開可以訪問(本專案中,對於登入和註冊的 URL,公開可以訪問)
  • 需要授權才能訪問

實踐與除錯

實現utils.JwtUtil類,建立、解析 jwt token
實現config.filter.JwtAuthenticationTokenFilter類,用來驗證 jwt token 是否合法有效,如果驗證成功,則將 User 資訊注入上下文中
配置config.SecurityConfig類,放行登入、註冊等介面

登入一般是 post 請求。

登入如果是 get 請求,會將使用者名稱和密碼引數放在 url 連結中,明文傳輸。顯然不能這樣。
選擇 Post 請求,就沒法從瀏覽器輸入 URL 的方式進行訪問,不能在瀏覽器中除錯。有 2 種除錯方式

  1. 前端 ajax 除錯
  2. 用 postman(以後學習)

對於返回的 token
比如:
"eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI5OWE5ZThjZDNlZDI0OTI3YTZiMWMzNDk5MDU1ZDljMyIsInN1YiI6IjEiLCJpc3MiOiJzZyIsImlhdCI6MTY1ODk3MjYzMCwiZXhwIjoxNjYwMTgyMjMwfQ.iioSQLuAyzpYLPzTgGuhs1ODb6mYIzpqnz6K8VQqbWc"
https://jwt.io/進行解析,可以得到對應的 userID。

相關文章