session、token、jwt區別分析

1.session

session不是在瀏覽器第一次請求時創建,而是在第一次使用時創建(request.getSession())。

最終創建邏輯在org.apache.catalina.connector.Request的doGetSession()方法中,如下代碼可以看到,這裏會讓請求方設置一個cookie:JSESSIONID

/* org.apache.catalina.connector.Request    doGetSession()   部分代碼  */
Cookie cookie = ApplicationSessionCookieConfig.createSessionCookie(context, this.session.getIdInternal(), this.isSecure());
this.response.addSessionCookieInternal(cookie);

在這裏插入圖片描述
注意:服務端使用一個ConcurrentHashMap存儲session,由於session是存儲在應用中的,因此也存在session集羣共享問題,爲解決session共享問題,可使用spring-session。

2.spring-session

spring-session就是把session的存儲從應用中剝離出來單獨存儲,一般存放在緩存如redis中,這樣應用集羣都從redis單機或集羣中獲取session,也就不存在session共享問題了。

在這裏插入圖片描述
使用spring-session的示例

在這裏插入圖片描述

3.token

session的主要作用就是存儲用戶相關數據,token作用與session類似,個人理解爲session的改進版。

token與session對比:

  • 客戶端sessionId存儲在瀏覽器的cookie中,token可以存儲在localStorage、cookie、sessionStorage中。
  • 服務端session存儲在應用中,token關聯的數據則可以存儲在應用或者緩存中。如果服務端重啓,session失效,token如果在緩存中則仍然有效。
  • 如果客戶端禁用cookie,session將失效,客戶端如果將token保存在非cookie中,則仍然有效。
  • token的邏輯需要單獨寫。

4.JWT

Json web token (JWT),用於作爲JSON對象在各方之間安全地傳輸信息。JWT由三個部分組成:header(頭部)、payload(載荷)、signature(簽名)。

header

tpy:聲明使用JWT,alg:用於生產簽名的算法

{
  'typ': 'JWT',
  'alg': 'HS256'
}

通過base64生成header部分:eyd0eXAnOidKV1QnLCdhbGcnOidIUzI1Nid9

payload

載荷一般存儲用戶相關信息,由於只進行base64編碼,因此不建議存儲敏感數據。

以下爲默認提供的字段,除此以外,可以使用自定義的字段如用戶名、暱稱等。

iss:發行人
exp:到期時間
sub:主題
aud:用戶
nbf:在此之前不可用
iat:發佈時間
jti:JWT ID用於標識該JWT

再構建完後同樣需要進行base64編碼生成payload部分。

signature

通過header、payload部分,再使用header中聲明的算法,結合鹽,最後通過base64編碼生成signature部分。

三部分使用 . 相連構成了最終的JWT——header.payload.signature。

在這裏插入圖片描述

缺點分析

  • 由於用戶相關數據從服務端轉移到客戶端JWT中的payload中,並且會隨每次請求攜帶,可以理解爲每次請求都會帶一些無用的數據,因此不建議payload存儲過多的數據。
  • 修改payload中的數據時需要重新構造JWT,因此如果payload中的數據修改較爲頻繁,建議使用session或token。
  • JWT過期時間不支持動態刷新,並且在有效期間JWT將一直生效,不能取消。

適用場景

  • 一次性驗證:如郵箱激活,好處是服務端不用保存激活相關的數據,都放到JWT的payload中了。
  • 接口鑑權:即作爲請求端有權訪問服務端的標識。

有關JWT詳細點的介紹可以觀看https://www.liqingbo.cn/docs/jwt/

——以上僅爲個人見解,如有不正確的地方歡迎指正!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章