幾種常見登錄驗證的方式總結


1. Cookie-Session 認證

早期互聯網以 web 為主,客戶端是瀏覽器,所以 Cookie-Session 方式最那時候最常用的方式,直到現在,一些 web 網站依然用這種方式做認證。
認證過程大致如下:

  1. 用戶輸入用戶名、密碼或者用短信驗證碼方式登錄系統;
  2. 服務端驗證后,返回一個 SessionId [SessionId與用戶信息進行關聯,通過SessionId可以得到用戶信息],客戶端將 SessionID 存到 cookie,下次訪問的時候帶着SessionID;
  3. 當客戶端再發起請求,自動帶上 cookie 信息,服務端通過 cookie 獲取 Session 信息進行校驗,判斷對應用戶是否存在;

弊端

  • 只能在 web 場景下使用,如果是 APP 中,不能使用 cookie 的情況下就不能用了;
  • 即使能在 web 場景下使用,也要考慮跨域問題,因為 cookie 不能跨域;
  • cookie 存在 CSRF(跨站請求偽造[前后端分離的項目])的風險;
  • 如果是分布式服務做了集群,第一次登錄請求訪問的是A服務,第二請求來到了B服務,B服務就沒有第一次請求訪問登錄得到的Session Id. 此時還需要考慮 Session 同步問題;



2. 基於 Cookie-Session 的改造認證

由於傳統的 Cookie-Session 認證存在諸多問題,可以把上面的方案改造一下。改動的地方如下:

  1. 不用 cookie 做客戶端存儲,改用其他方式,web 場景下讓前端使用 local storage(局部存儲器。它是html5新增的一個本地存儲API),APP 中使用客戶端數據庫,這樣就實現了跨域,並且避免了 CSRF ;
  2. 服務端也不存 Session 了,把 Session 信息拿出來存到 Redis 等內存數據庫中,這樣即提高了速度,又避免了 Session 同步問題;

經過改造之后變成了如下的認證過程:

  1. 用戶輸入用戶名、密碼或者用短信驗證碼方式登錄系統;
  2. 服務端經過驗證,將認證信息構造好的數據結構存儲到 Redis 中,並將 key 值返回給客戶端;
  3. 客戶端拿到返回的 key,存儲到 local storage 或本地數據庫;
  4. 下次客戶端再次請求,把 key 值附加到 header 或者 請求體中;
  5. 服務端根據獲取的 key,到 Redis 中獲取查詢相關value得到認證信息;

弊端:

  1. 可能存在單點故障的問題,redis宕機后,全部用戶都得重新登錄。
  2. redis可以做集群解決單點故障問題。但回過頭來一想, 就為了這小小的session我還得為他付出這么多精力,得不償失。
  3. 也會占用redis的內存,用戶多的話,要占很多redis內存。



3. Token認證

例子:https://blog.csdn.net/qq_20786911/article/details/104687728?utm_source=app&app_version=4.10.0
認證過程大致如下:

  1. 用戶在登錄表單中輸入用戶名和密碼,然后點擊登錄。服務端會返回一個token。訪問其他接口的時候帶着token。
  2. 請求通過在請求頭中攜帶token發送登錄請求之后,通過在后端查詢數據庫驗證用戶的合法性。【通常會讓用戶表與token有關聯關系,一般還會對token加密,而且還會設置過期時間。所以會一般采用redis來存儲,key存token,值存用戶相關信息】
  3. 在每次發送訪問請求時提供token信息(一般是服務器采用filter過濾器或攔截器來判斷),然后根據這個token得到相關用戶信息(如:用戶id)去數據庫查得到用戶信息進行驗證賬號密碼等,通過則讓用戶訪問服務端接口,不通過則拒絕訪問。

弊端:

  1. 這一切其實和session id沒有本質區別。
  2. 需要用token去redis數據庫查詢是否有相應用戶。
  3. 也會占用redis的內存,用戶多的話,要占很多redis內存。



4. 基於Token的JWT認證

JWT:Json web token 是為了在網絡應用環境間傳遞聲明而執行的一種基於JSON傳輸格式的開放標准,可實現無狀態、分布式的Web應用授權。

先說缺點:
使用JWT時,有個十分頭疼的問題。用戶主動注銷,服務器不能讓token主動失效。就是說token沒有過期前,你想讓它提前停止使用,不好意思沒得辦法。
解決思路有幾種,不過都不是很完美。要么你就不解決JWT退出登錄的問題,你在設置對token設置過期的時候,不要設置太久,設置1天,1天過后就失效。

再說優點:
他是一種行業都認可的開發標准,JWT他就是用於web開發的JSON形式的token,我們現在的開發模式都是前后端分離,數據傳輸就是用的JSON。這個token不像第三點的token,現在這個token有標准了。有定義規范了,按照規范來定義使用它,你可以達到不將其保存到redis數據庫。

認證過程大致如下:

  1. 用戶登陸服務器,服務端驗證用戶賬號密碼,使用secret生成JWT令牌【一般還會設置過期時間,在生成token的時候指定】,然后將令牌返回給客戶端。
  2. 客戶端訪問服務端的時候,在請求頭中帶上這個令牌,服務端使用secret去驗證令牌是否合法,合法則讓用戶訪問服務器接口,不合法則拒絕。
  3. 服務器並不保存token,就不用像上述方式,拿到token還得去redis數據庫驗證,根據token得到對應值(一般時用戶的id,拿到用戶id后,判斷用戶存不存在,用戶不存在直接返回用戶不存在,JWT提供了一個verify方法可以用於驗證該TOKEN是否有效[就是密碼正不正確])。(注意理解這里,因為生成的JWT令牌(是按照某種規則生成的,它可以包含用戶信息,比如我們把用戶id或帶有權限標識的用戶JSON數據[做權限校驗]存到JWT令牌,他第二次帶着JWT令牌登錄時,解析JWT令牌得到他的用戶id,此時拿着用戶id去查詢那個用戶信息,得到賬號密碼進行校驗。))。

JWT令牌結構:

    Header(頭部)        是token的一部分,用來存放token的類型和編碼方式,通常是使用base-64編碼
    Payload(負載)       包含了信息,你可以存放任一種信息,比如用戶信息,產品信息等,它們都是使用base-64編碼方式【編碼方式取決於你在Header中設置的編碼方式】進行存儲
    Signature(簽名)     包括了header,payload和密鑰的混合體,密鑰必須安全地保存儲在服務端

    發送給服務器的令牌樣子是AAAA(頭部).BBBB(負載).CCCC(簽名)的形式。

Header:
通常由兩部分組成,令牌的類型與所使用的簽名算法。它會被Base64編碼編成JWT結構的第一部分。【Base64編碼:不是一種加密,就是一種編碼,它能被解碼】

{
  "alg":"HS256",  // 簽名算法  默認 HS256
  "typ":"JWT"  // 令牌的類型  默認 JWT
}

Payload:
用於包含聲明信息,一般用來聲明用戶數據。它會被Base64編碼編成JWT結構的第二部分。【Base64編碼:不是一種加密,就是一種編碼,它能被解碼】
因為能被解密,所以這里面不要放特別敏感的用戶信息。

{
  "name":"zhangsan",
  "age":23,
  "email":"971410648@qq.com"
}

Signature:
他是基於Header,Payload被Base64編碼后加上我們提供的一個私鑰,這個私鑰只有服務端知道,然后就會將3者使用Header里面指定的簽名算法進行簽名生成JWT。
作用:保證JWT沒有被篡改。

token = `${base64UrlEncode(header)}.${base64UrlEncode(payload)}`.signature)





5. SSO單點登錄

單點登錄:指在公司內部搭建一個公共的認證中心,公司下的所有產品的登錄都可以在認證中心里完成,一個產品在認證中心登錄后,再去訪問另一個產品時,可以不用再登錄,即可獲取登錄狀態。



6. OAuth第三方登錄



7. 總結

  • Cookie + Session 歷史悠久,適合於簡單的后端架構,需開發人員自己處理好安全問題。
  • 基於Token的JWT 方案對后端壓力小,適合大型分布式的后端架構,但已分發出去的 token ,如果想收回權限,就不是很方便了。
  • SSO 單點登錄,適用於中大型企業,想要統一內部所有產品的登錄方式。
  • OAuth 第三方登錄,簡單易用,對用戶和開發者都友好,但第三方平台很多,需要選擇合適自己的第三方登錄平台


8. JWT登錄案例:

基於自定義注解+攔截器實現(沒有指定過期時間):https://blog.csdn.net/qq_37992974/article/details/90236581?utm_source=app&app_version=4.10.0
基於自定義注解+攔截器實現(指定過期時間):https://blog.csdn.net/lzm19930310/article/details/109626578?utm_source=app&app_version=4.10.0
不使用注解+攔截器實現:https://blog.csdn.net/weixin_47025166/article/details/125373122
設置過期時間:https://blog.csdn.net/qq_33229669/article/details/87204400?utm_source=app&app_version=4.10.0

如何讓token失效:https://blog.csdn.net/weixin_39777213/article/details/113410928?utm_source=app&app_version=4.10.0


免責聲明!

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



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