日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

一文徹底理清session、cookie、token的區別_相關技巧

作者:W-MoMo ? 更新時間: 2023-06-20 編程語言

前言

今天就來理一理session、cookie、token這三者之間的關系!

1.為什么會有它們?

我們都知道 HTTP 協議是無狀態的,所謂的無狀態就是客戶端每次想要與服務端通信,都必須重新與服務端鏈接,意味著請求一次客戶端和服務端就連接一次,下一次請求與上一次請求是沒有關系的。

這種無狀態的方式就會存在一個問題:如何判斷兩次請求的是同一個人?就好比用戶在頁面 A 發起請求獲取個人信息,然后在另一個頁面同樣發起請求獲取個人信息,我們如何確定這倆個請求是同一個人發的呢?

為了解決這種問題,我們就迫切需要一種方式知道發起請求的客戶端是誰?此時,cookie、token、session 就出現了,它們就可以解決客戶端標識的問題,在擴大一點就是解決權限問題。

它們就好比讓每個客戶端或者說登錄用戶有了自己的身份證,我們可以通過這個身份證確定發請求的是誰!

2.什么是 cookie?

cookie 是保存在客戶端或者說瀏覽器中的一小塊數據,大小限制大致在 4KB 左右,在以前很多開發人員通常用 cookie 來存儲各種數據,后來隨著更多瀏覽器存儲方案的出現,cookie 存儲數據這種方式逐漸被取代,主要原因有如下:

  • cookie 有存儲大小限制,4KB 左右。
  • 瀏覽器每次請求會攜帶 cookie 在請求頭中。
  • 字符編碼為 Unicode,不支持直接存儲中文。
  • 數據可以被輕易查看。

cookie 主要有以下屬性:

屬性名稱 屬性含義
name cookie 的名稱
value cookie 的值
comment cookie 的描述信息
domain 可以訪問該 cookie 的域名
expires cookie 的過期時間,具體某一時間
maxAge cookie 的過期時間,比如多少秒后 cookie 過期。
path cookie 的使用路徑,
secure cookie 是否使用安全協議傳輸,比如 SSL 等
version cookie 使用的版本號
isHttpOnly 指定該 Cookie 無法通過 JavaScript 腳本拿到,比如 Document.cookie 屬性、XMLHttpRequest 對象和 Request API 都拿不到該屬性。這樣就防止了該 Cookie 被腳本讀到,只有瀏覽器發出 HTTP 請求時,才會帶上該 Cookie。

我們介紹了 cookie,那么我們是如何通過 cookie 來實現用戶確定或者權限的確定呢?

我們就以一個普通網站的用戶登錄操作以及后續操作為例,主要過程可以簡單用下圖表示:

從上圖中可以看到使用 cookie 進行用戶確認流程是比較簡單的,大致分為以下幾步:

  1. 客戶端發送請求到服務端(比如登錄請求)。
  2. 服務端收到請求后生成一個 session 會話。
  3. 服務端響應客戶端,并在響應頭中設置 Set-Cookie。Set-Cookie 里面包含了 sessionId,它的格式如下:Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]。其中 sessionId 就是用來標識客戶端的,類似于去飯店里面,服務員給你一個號牌,后續上菜通過這個號牌來判斷上菜到哪里。
  4. 客戶端收到該請求后,如果服務器給了 Set-Cookie,那么下次瀏覽器就會在請求頭中自動攜帶 cookie。
  5. 客戶端發送其它請求,自動攜帶了 cookie,cookie 中攜帶有用戶信息等。
  6. 服務端接收到請求,驗證 cookie 信息,比如通過 sessionId 來判斷是否存在會話,存在則正常響應。

cookie 主要有以下特點:

  • cookie 存儲在客戶端
  • cookie 不可跨域,但是在如果設置了 domain,那么它們是可以在一級域名和二級域名之間共享的。

3.什么是 session?

在上一節中,我們通過 Cookie 來實現了用戶權限的確認,在其中我們提到了一個詞:session。顧名思義它就是會話的意思,session 主要由服務端創建,主要作用就是保存 sessionId,用戶與服務端之間的權限確認主要就是通過這個 sessionId。

簡單描述下 session:

session 由服務端創建,當一個請求發送到服務端時,服務器會檢索該請求里面有沒有包含 sessionId 標識,如果包含了 sessionId,則代表服務端已經和客戶端創建過 session,然后就通過這個 sessionId 去查找真正的 session,如果沒找到,則為客戶端創建一個新的 session,并生成一個新的 sessionId 與 session 對應,然后在響應的時候將 sessionId 給客戶端,通常是存儲在 cookie 中。如果在請求中找到了真正的 session,驗證通過,正常處理該請求。

總之每一個客戶端與服務端連接,服務端都會為該客戶端創建一個 session,并將 session 的唯一標識 sessionId 通過設置 Set-Cookie 頭的方式響應給客戶端,客戶端將 sessionId 存到 cookie 中。

通常情況下,我們 cookie 和 session 都是結合著來用,當然你也可以單獨只使用 cookie 或者單獨只使用 session,這里我們就將 cookie 和 session 結合著來用。

我們可以在修改一下整個請求過程圖,如下所示:

4.cookie 和 session 的區別?

前面兩節我們介紹了 cookie 和 session,它們兩者之間主要是通過 sessionId 關聯起來的,所以我們總結出:sessionId 是 cookie 和 session 之間的橋梁。我們日常的系統中如果在鑒權方面如果使用的是 cookie 方式,那么大部分的原理就和我們前面說的一樣。

或者我們可以換個說法,session 是基于 cookie 實現的,它們兩個主要有以下特點:

  • session 比 cookie 更加安全,因為它是存在服務端的,cookie 是存在客戶端的。
  • cookie 只支持存儲字符串數據,session 可以存儲任意數據。
  • cookie 的有效期可以設置較長時間,session 有效期都比較短。
  • session 存儲空間很大,cookie 有限制。

系統想要實現鑒權,可以單獨使用 cookie,也可以單獨使用 session,但是建議結合兩者使用。

5.token 是什么?

前面我們說的 sessionId 可以叫做令牌,令牌顧名思義就是確認身份的意思,服務端可以通過令牌來確認身份。

cookie+session 是實現認證的一種非常好的方式,但是凡事都有兩面性,它們實現的認證主要有以下缺點:

  • 增加請求體積,浪費性能,因為每次請求都會攜帶 cookie。
  • 增加服務端資源消耗,因為每個客戶端連接進來都需要生成 session,會占用服務端資源的。
  • 容易遭受 CSRF 攻擊,即跨站域請求偽造。

那么為了避免這些缺點,token 方式的鑒權出現了,它可以說是一個民間的認證方式,但是不得不說它帶來了非常多的好處。

token 的組成:

token 其實就是一串字符串而已,只不過它是被加密后的字符串,它通常使用 uid(用戶唯一標識)、時間戳、簽名以及一些其它參數加密而成。我們將 token 進行解密就可以拿到諸如 uid 這類的信息,然后通過 uid 來進行接下來的鑒權操作。

token 是如何生成的:

前面我們說 cookie 是服務端設置了 set-cookie 響應頭之后,瀏覽器會自動保存 cookie,然后下一次發送請求的時候會自動把 cookie 攜帶上。但是我們說 cookie 算是一種民間的實現方式,所以說瀏覽器自然不會對它進行成么處理。token 主要是由服務器生成,然后返回給客戶端,客戶端手動把 token 存下來,比如利用 localstorage 或者直接存到 cookie 當中也行。

token 認證流程:

  1. 客戶端發起登錄請求,比如用戶輸入用戶名和密碼后登錄。
  2. 服務端校驗用戶名和密碼后,將用戶 id 和一些其它信息進行加密,生成 token。
  3. 服務端將 token 響應給客戶端。
  4. 客戶端收到響應后將 token 存儲下來。
  5. 下一次發送請求后需要將 token 攜帶上,比如放在請求頭中或者其它地方。
  6. 服務端 token 后校驗,校驗通過則正常返回數據。

用圖表示大致如下:

format,png

總結

雖然前面解釋 cookie、session、token 用了不少口舌,但是歸根結底啊,它們的目的都是一樣的:鑒權和認證。

鑒權認證方式 特點 優點 缺點
cookie 1.存儲在客戶端。2.請求自動攜帶 cookie。3.存儲大小 4KB。 1.兼容性好,因為是比較老的技術。2.很容易實現,因為 cookie 會自動攜帶和存儲。 1.需要單獨解決跨域攜帶問題,比如多臺服務器如何共享 cookie。2.會遭受 CSRF 攻擊。3.存儲在客戶端,不夠安全。
session 1.存儲在服務端。2.存儲大小無限制。 1.查詢速度快,因為是個會話,相當于是在內存中操作。2.結合 cookie 后很容易實現鑒權。3.安全,因為存儲在服務端。 1.耗費服務器資源,因為每個客戶端都會創建 session。2.占據存儲空間,session 相當于存儲了一個完整的用戶信息。
token 1.體積很小。2.自由操作存儲在哪里。 1.安全,因為 token 一般只有用戶 id,就算被截取了也沒什么用。2.無需消耗服務器內存資源,它相當于只存了用戶 id,session 相當于存儲了用戶的所有信息。3.跨域處理較為方便,比如多臺服務器之間可以共用一個 token。 1.查詢速度慢,因為 token 只存了用戶 id,每次需要去查詢數據庫。

總結下來就是:session 是空間換時間,token 是時間換空間。

附:cookie/session的聯系

session雖說存放在服務器端,但是仔細看剛才的執行流程你會明白,session是依賴于cookie的,這一點也是本篇文章想要著重強調的

7.cookie/session使用注意事項

1.cookie大小有限制 4k

2.cookie不能跨瀏覽器

3.cookie不支持中文

4.如果是安全性較高的數據應存放在session中,因為cookie存放在客戶端總會輕易被不法分子獲取

5.如果是訪問量特別大的網站,盡量不要在session中存儲用戶數據,因為每個用戶存一個session會給服務器造成很大的壓力

但需要注意的是,若服務器做了負載均衡,用戶的下一次請求可能會被定向到其它服務器節點,若那臺節點上沒有用戶的Session信息,就會導致會話驗證失敗。所以Session默認機制下是不適合分布式部署的。

原文鏈接:https://blog.csdn.net/m0_65489440/article/details/125676761

  • 上一篇:沒有了
  • 下一篇:沒有了
欄目分類
最近更新