Session認證機制與JWT認證機制

一、什麼是身份認證?

身份認證(Authentication)又稱「身份驗證」、「鑒權」,是指通過一定的手段,完成對用戶身份的確認。
日常生活中的身份認證隨處可見,例如:高鐵的驗票乘車,手機的密碼或指紋解鎖,支付寶或微信的支付密碼等。
在Web開發中,也涉及到用戶身份的認證,例如:各大網站的手機驗證碼登錄、郵箱密碼登錄、二維碼登錄等。

二、為什麼需要身份認證?

  身份認證的目的,是為了確認當前所聲稱為某種身份的用戶,確實是所聲稱的用戶。
  例如,你去找快遞員取快遞,你要怎麼證明這份快遞是你的。
  一句話:如何證明你是你?

三、Session認證機制

  1.HTTP請求的無狀態性
    HTTP 協議的無狀態性,指的是客戶端的每次 HTTP 請求都是獨立的,連續多個請求之間沒有直接的關係,伺服器不會主動保留每次 HTTP 請求的狀態。
  2.使用 Cookie 突破 HTTP 請求的無狀態性
    2.1 什麼是 Cookie
      Cookie 是存儲在用戶瀏覽器中的一段不超過 4 KB 的字元串。它由一個名稱(Name)、一個值(Value)和其它幾個用於控制 Cookie 有效期、安全性、使用範圍的可選屬性組成。
      不同域名下的 Cookie 各自獨立,每當客戶端發起請求時,會自動把當前域名下所有未過期的 Cookie 一同發送到伺服器。
    2.2 Cookie的四大特點
      自動發送,域名獨立,過期時限,4KB大小限制
  3.Cookie 在身份認證中的作用
    客戶端第一次請求伺服器的時候,伺服器通過響應頭的形式,向客戶端發送一個身份認證的 Cookie,客戶端會自動將 Cookie 保存在瀏覽器中。
    隨後,當客戶端瀏覽器每次請求伺服器的時候,瀏覽器會自動將身份認證相關的 Cookie,通過請求頭的形式發送給伺服器,伺服器即可驗明客戶端的身份。

  

  4. Cookie 不具有安全性
    由於 Cookie 是存儲在瀏覽器中的,而且瀏覽器也提供了讀寫 Cookie 的 API,因此 Cookie 很容易被偽造,不具有安全性。
    因此不建議伺服器將重要的隱私數據,通過 Cookie 的形式發送給瀏覽器。
  5. 提高身份認證的安全性—Session認證機制

  

  6.Session認證的局限性
    Session 認證機制需要配合 Cookie 才能實現。由於 Cookie 默認不支援跨域訪問,所以,當涉及到前端跨域請求後端介面的時候,需要做很多額外的配置,才能實現跨域 Session 認證。
  7.Cookie與Session的區別
  (1)存儲位置不同:
    Cookie 存儲在瀏覽器當中,Session 存儲在伺服器當中。
  (2)安全性不同
    Cookie 存儲在瀏覽器中,瀏覽器提供獲取和修改 Cookie 的API,使得Cookie很容易遭到篡改,而 Session 保存在伺服器當中,相對Cookie更加安全。
  (3)有效期不同
    Cookie 的有效期很久,甚至可以是永久,但是Session為了減輕伺服器的壓力,會定期清除長時間沒有被訪問過的(超時的)Session以減輕伺服器壓力。
  (4)對伺服器壓力不同
    Session保存在伺服器,每個用戶都有一個Session,如果訪問量過大,用戶過多,會對伺服器造成壓力。Cookie保存在客戶端,不佔用伺服器資源。

四、JWT認證機制

  1.JWT的工作原理

  

  總結:用戶的資訊通過 Token 字元串的形式,保存在客戶端瀏覽器中。伺服器通過還原 Token 字元串的形式來認證用戶的身份。
  2.JWT的組成部分
    JWT 的三個組成部分,從前到後分別是 Header、Payload、Signature。
    Payload 部分才是真正的用戶資訊,它是用戶資訊經過加密之後生成的字元串。
    Header 和 Signature 是安全性相關的部分,只是為了保證 Token 的安全性。
  3. JWT 的使用方式
    客戶端收到伺服器返回的 JWT 之後,通常會將它儲存在 localStorage 或 sessionStorage 中。
    此後,客戶端每次與伺服器通訊,都要帶上這個 JWT 的字元串,從而進行身份認證。推薦的做法是把 JWT 放在 HTTP 請求頭的 Authorization 欄位中。

五、Session認證機制與JWT認證機制應用場景

  服務端渲染、不跨域時推薦使用Session
  前後端分離、跨域時推薦使用JWT

六、Cookie/Session和JWT的優缺點

  三者共同點:三者都是應用在web中對http無狀態協議的補充,達到狀態保持
    cokkie:cookie中的資訊是以鍵值對的形式儲存在瀏覽器中的,而且在瀏覽器中可以直接看到數據
    session:session存儲在伺服器中,然後發送一個cookie存儲在瀏覽器中,cookie中存儲的是session_id通過session_id請求伺服器可以獲取對應的session資訊.
    jwt:由伺服器產生加密的json數據包括,header,payload,signature三部分組成,header中通常來說由token的生成演算法和類型組成。
    payload中則用來保存相關的狀態資訊。signature部分由header,payload,secret_key三部分加密生成。
  1、存儲差異
    cookie資訊和jwt存儲在客戶端,session資訊存儲在服務端,但是cookie是瀏覽器客戶端獨有的。
  2、優劣
    2.1、cookie:
    cookie優點:
      2.1.1:簡單性 Cookie 是一種基於文本的輕量結構,包含簡單的鍵值對。
      2.1.2:數據持久性 雖然客戶端電腦上 Cookie 的持續時間取決於客戶端上的 Cookie 過期處理和用戶干預,Cookie 通常是客戶端上持續時間最長的數據保留形式。
    cookie缺點:
      2.1.3:大小受到限制 ,大多數瀏覽器對 Cookie 的大小有 4096 位元組的限制,儘管在當今新的瀏覽器和客戶端設備版本中,支援 8192 位元組的 Cookie 大小已愈發常見。
      2.1.4:非常不安全,cookie將數據裸露在瀏覽器中,這樣大大增大了數據被盜取的風險,所有我們不應該將中要的數據放在cookie中,或者將數據加密處理。
      2.1.5:容易被csrf攻擊,可以設置csrf_token來避免攻擊。
    2.2、session:
    session優點:
      2.2.1:session中的資訊存儲在服務端,相比於cookie就在一定程度上加大了數據的安全性。
      2.2.2:session數據存儲在服務端,相比於jwt方便進行管理,也就是說當用戶登錄和主動註銷,只需要添加刪除對應的session就可以,這樣管理起來很方便。
    session缺點:
      2.2.3:session存儲在服務端,這就增大了伺服器的開銷,當用戶多的情況下,伺服器性能會大大降低。
      2.2.4:因為是基於cookie來進行用戶識別的, cookie如果被截獲,用戶就會很容易受到跨站請求偽造的攻擊。
      2.2.5:用戶認證之後,服務端做認證記錄,如果認證的記錄被保存在記憶體中的話,這意味著用戶下次請求還必須要請求在這台伺服器上,這樣才能拿到授權的資源,
          這樣在分散式的應用上,相應的限制了負載均衡器的能力。這也意味著限制了應用的擴展能力。
    2.3、jwt:
    jwt優點:
      2.3.1:因為json的通用性,jwt可以支援跨語言請求,像JAVA,JavaScript,NodeJS,PHP等很多語言都可以使用。
      2.3.2:因為有了payload部分,所以JWT可以在自身存儲一些其他業務邏輯所必要的非敏感資訊。
      2.3.3:便於傳輸,jwt的構成非常簡單,位元組佔用很小,所以它是非常便於傳輸的。
      2.3.4:它不需要在服務端保存會話資訊, 所以它易於應用的擴展,即資訊不保存在服務端,不會存在session擴展不方便的情況。
    jwt缺點:
      2.3.5:登錄狀態資訊續簽問題。比如設置token的有效期為一個小時,那麼一個小時後,如果用戶仍然在這個web應用上,這個時候當然不能指望用戶再登錄一次。
         目前可用的解決辦法是在每次用戶發出請求都返回一個新的token,前端再用這個新的token來替代舊的,這樣每一次請求都會刷新token的有效期。
         但是這樣,需要頻繁的生成token。這個方法不僅暴力不優雅,而且每次請求都要做jwt的加密解密,會帶來性能問題。
         另一種方法是在redis中單獨為每個jwt設置過期時間,每次訪問時刷新jwt的過期時間。
      2.3.6:用戶主動註銷。JWT並不支援用戶主動退出登錄,當然,可以在客戶端刪除這個token,但在別處使用的token仍然可以正常訪問。
         為了支援註銷,我的解決方案是在註銷時將該token加入黑名單。
    使用jwt注意點:
      2.3.7:在payload中不應該存放敏感資訊,以為該部分客戶端是可以解密的。
      2.3.8:secret_key不能泄露。
    適合使用jwt的場景:
      2.3.9:有效期短
      2.3.10:只希望被使用一次
      比如,用戶註冊後發一封郵件讓其激活賬戶,通常郵件中需要有一個鏈接,這個鏈接需要具備以下的特性:
      能夠標識用戶,該鏈接具有時效性(通常只允許幾小時之內激活),不能被篡改以激活其他可能的賬戶,一次性的。這種場景就適合使用jwt。
      而由於jwt具有一次性的特性。單點登錄和會話管理非常不適合用jwt,如果在服務端部署額外的邏輯存儲jwt的狀態,那還不如使用session。
      基於session有很多成熟的框架可以開箱即用,但是用jwt還要自己實現邏輯。

參考:

//blog.csdn.net/qq_59181609/article/details/125731296

//cloud.tencent.com/developer/article/1773610

//blog.csdn.net/weixin_61422097/article/details/120454714

token可以存儲在cookie中嗎

//www.nowcoder.com/exam/interview/detail?questionClassifyId=0&questionId=2412490&questionJobId=156&type=1

Tags: