看完這篇 Session、Cookie、Token,和面試官扯皮就沒(méi)問(wèn)題了

      網(wǎng)友投稿 999 2025-04-01

      Cookie 和 Session

      HTTP 協(xié)議是一種無(wú)狀態(tài)協(xié)議,即每次服務(wù)端接收到客戶端的請(qǐng)求時(shí),都是一個(gè)全新的請(qǐng)求,服務(wù)器并不知道客戶端的歷史請(qǐng)求記錄;Session 和 Cookie 的主要目的就是為了彌補(bǔ) HTTP 的無(wú)狀態(tài)特性。

      Session 是什么

      客戶端請(qǐng)求服務(wù)端,服務(wù)端會(huì)為這次請(qǐng)求開(kāi)辟一塊內(nèi)存空間,這個(gè)對(duì)象便是 Session 對(duì)象,存儲(chǔ)結(jié)構(gòu)為 ConcurrentHashMap。Session 彌補(bǔ)了 HTTP 無(wú)狀態(tài)特性,服務(wù)器可以利用 Session 存儲(chǔ)客戶端在同一個(gè)會(huì)話期間的一些操作記錄。

      看完這篇 Session、Cookie、Token,和面試官扯皮就沒(méi)問(wèn)題了

      Session 如何判斷是否是同一會(huì)話

      服務(wù)器第一次接收到請(qǐng)求時(shí),開(kāi)辟了一塊 Session 空間(創(chuàng)建了Session對(duì)象),同時(shí)生成一個(gè) sessionId ,并通過(guò)響應(yīng)頭的 **Set-Cookie:JSESSIONID=XXXXXXX **命令,向客戶端發(fā)送要求設(shè)置 Cookie 的響應(yīng); 客戶端收到響應(yīng)后,在本機(jī)客戶端設(shè)置了一個(gè) **JSESSIONID=XXXXXXX **的 Cookie 信息,該 Cookie 的過(guò)期時(shí)間為瀏覽器會(huì)話結(jié)束;

      接下來(lái)客戶端每次向同一個(gè)網(wǎng)站發(fā)送請(qǐng)求時(shí),請(qǐng)求頭都會(huì)帶上該 Cookie信息(包含 sessionId ), 然后,服務(wù)器通過(guò)讀取請(qǐng)求頭中的 Cookie 信息,獲取名稱為 JSESSIONID 的值,得到此次請(qǐng)求的 sessionId。

      Session 的缺點(diǎn)

      Session 機(jī)制有個(gè)缺點(diǎn),比如 A 服務(wù)器存儲(chǔ)了 Session,就是做了負(fù)載均衡后,假如一段時(shí)間內(nèi) A 的訪問(wèn)量激增,會(huì)轉(zhuǎn)發(fā)到 B 進(jìn)行訪問(wèn),但是 B 服務(wù)器并沒(méi)有存儲(chǔ) A 的 Session,會(huì)導(dǎo)致 Session 的失效。

      Cookies 是什么

      HTTP 協(xié)議中的 Cookie 包括 Web Cookie 和瀏覽器 Cookie,它是服務(wù)器發(fā)送到 Web 瀏覽器的一小塊數(shù)據(jù)。服務(wù)器發(fā)送到瀏覽器的 Cookie,瀏覽器會(huì)進(jìn)行存儲(chǔ),并與下一個(gè)請(qǐng)求一起發(fā)送到服務(wù)器。通常,它用于判斷兩個(gè)請(qǐng)求是否來(lái)自于同一個(gè)瀏覽器,例如用戶保持登錄狀態(tài)。

      HTTP Cookie 機(jī)制是 HTTP 協(xié)議無(wú)狀態(tài)的一種補(bǔ)充和改良

      Cookie 主要用于下面三個(gè)目的

      會(huì)話管理

      登陸、購(gòu)物車、游戲得分或者服務(wù)器應(yīng)該記住的其他內(nèi)容

      個(gè)性化

      用戶偏好、主題或者其他設(shè)置

      追蹤

      記錄和分析用戶行為

      Cookie 曾經(jīng)用于一般的客戶端存儲(chǔ)。雖然這是合法的,因?yàn)樗鼈兪窃诳蛻舳松洗鎯?chǔ)數(shù)據(jù)的唯一方法,但如今建議使用現(xiàn)代存儲(chǔ) API。Cookie 隨每個(gè)請(qǐng)求一起發(fā)送,因此它們可能會(huì)降低性能(尤其是對(duì)于移動(dòng)數(shù)據(jù)連接而言)。

      創(chuàng)建 Cookie

      當(dāng)接收到客戶端發(fā)出的 HTTP 請(qǐng)求時(shí),服務(wù)器可以發(fā)送帶有響應(yīng)的 Set-Cookie 標(biāo)頭,Cookie 通常由瀏覽器存儲(chǔ),然后將 Cookie 與 HTTP 標(biāo)頭一同向服務(wù)器發(fā)出請(qǐng)求。

      Set-Cookie HTTP 響應(yīng)標(biāo)頭將 cookie 從服務(wù)器發(fā)送到用戶代理。下面是一個(gè)發(fā)送 Cookie 的例子

      此標(biāo)頭告訴客戶端存儲(chǔ) Cookie

      現(xiàn)在,隨著對(duì)服務(wù)器的每個(gè)新請(qǐng)求,瀏覽器將使用 Cookie 頭將所有以前存儲(chǔ)的 Cookie 發(fā)送回服務(wù)器。

      有兩種類型的 Cookies,一種是 Session Cookies,一種是 Persistent Cookies,如果 Cookie 不包含到期日期,則將其視為會(huì)話 Cookie。會(huì)話 Cookie 存儲(chǔ)在內(nèi)存中,永遠(yuǎn)不會(huì)寫(xiě)入磁盤(pán),當(dāng)瀏覽器關(guān)閉時(shí),此后 Cookie 將永久丟失。如果 Cookie 包含有效期 ,則將其視為持久性 Cookie。在到期指定的日期,Cookie 將從磁盤(pán)中刪除。

      還有一種是 Cookie的 Secure 和 HttpOnly 標(biāo)記,下面依次來(lái)介紹一下

      上面的示例創(chuàng)建的是會(huì)話 Cookie ,會(huì)話 Cookie 有個(gè)特征,客戶端關(guān)閉時(shí) Cookie 會(huì)刪除,因?yàn)樗鼪](méi)有指定Expires或 Max-Age 指令。

      但是,Web 瀏覽器可能會(huì)使用會(huì)話還原,這會(huì)使大多數(shù)會(huì)話 Cookie 保持永久狀態(tài),就像從未關(guān)閉過(guò)瀏覽器一樣。

      永久性 Cookie 不會(huì)在客戶端關(guān)閉時(shí)過(guò)期,而是在特定日期(Expires)或特定時(shí)間長(zhǎng)度(Max-Age)外過(guò)期。例如

      Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;

      1

      安全的 Cookie 需要經(jīng)過(guò) HTTPS 協(xié)議通過(guò)加密的方式發(fā)送到服務(wù)器。即使是安全的,也不應(yīng)該將敏感信息存儲(chǔ)在cookie 中,因?yàn)樗鼈儽举|(zhì)上是不安全的,并且此標(biāo)志不能提供真正的保護(hù)。

      HttpOnly 的作用

      會(huì)話 Cookie 中缺少 HttpOnly 屬性會(huì)導(dǎo)致攻擊者可以通過(guò)程序(JS腳本、Applet等)獲取到用戶的 Cookie 信息,造成用戶 Cookie 信息泄露,增加攻擊者的跨站腳本攻擊威脅。

      HttpOnly 是微軟對(duì) Cookie 做的擴(kuò)展,該值指定 Cookie 是否可通過(guò)客戶端腳本訪問(wèn)。

      如果在 Cookie 中沒(méi)有設(shè)置 HttpOnly 屬性為 true,可能導(dǎo)致 Cookie 被竊取。竊取的 Cookie 可以包含標(biāo)識(shí)站點(diǎn)用戶的敏感信息,如 ASP.NET 會(huì)話 ID 或 Forms 身份驗(yàn)證票證,攻擊者可以重播竊取的 Cookie,以便偽裝成用戶或獲取敏感信息,進(jìn)行跨站腳本攻擊等。

      Cookie 的作用域

      Domain 和 Path 標(biāo)識(shí)定義了 Cookie 的作用域:即 Cookie 應(yīng)該發(fā)送給哪些 URL。

      Domain 標(biāo)識(shí)指定了哪些主機(jī)可以接受 Cookie。如果不指定,默認(rèn)為當(dāng)前主機(jī)(不包含子域名)。如果指定了Domain,則一般包含子域名。

      例如,如果設(shè)置 Domain=mozilla.org,則 Cookie 也包含在子域名中(如developer.mozilla.org)。

      例如,設(shè)置 Path=/docs,則以下地址都會(huì)匹配:

      /docs

      /docs/Web/

      /docs/Web/HTTP

      JSON Web Token 和 Session Cookies 的對(duì)比

      JSON Web Token ,簡(jiǎn)稱 JWT,它和 Session都可以為網(wǎng)站提供用戶的身份認(rèn)證,但是它們不是一回事。

      下面是 JWT 和 Session 不同之處的研究

      JWT 和 Session Cookies 的相同之處

      在探討 JWT 和 Session Cookies 之前,有必要需要先去理解一下它們的相同之處。

      它們既可以對(duì)用戶進(jìn)行身份驗(yàn)證,也可以用來(lái)在用戶單擊進(jìn)入不同頁(yè)面時(shí)以及登陸網(wǎng)站或應(yīng)用程序后進(jìn)行身份驗(yàn)證。

      如果沒(méi)有這兩者,那你可能需要在每個(gè)頁(yè)面切換時(shí)都需要進(jìn)行登錄了。因?yàn)?HTTP 是一個(gè)無(wú)狀態(tài)的協(xié)議。這也就意味著當(dāng)你訪問(wèn)某個(gè)網(wǎng)頁(yè),然后單擊同一站點(diǎn)上的另一個(gè)頁(yè)面時(shí),服務(wù)器的內(nèi)存中將不會(huì)記住你之前的操作。

      因此,如果你登錄并訪問(wèn)了你有權(quán)訪問(wèn)的另一個(gè)頁(yè)面,由于 HTTP 不會(huì)記錄你剛剛登錄的信息,因此你將再次登錄。

      JWT 和 Session Cookies 就是用來(lái)處理在不同頁(yè)面之間切換,保存用戶登錄信息的機(jī)制。

      也就是說(shuō),這兩種技術(shù)都是用來(lái)保存你的登錄狀態(tài),能夠讓你在瀏覽任意受密碼保護(hù)的網(wǎng)站。通過(guò)在每次產(chǎn)生新的請(qǐng)求時(shí)對(duì)用戶數(shù)據(jù)進(jìn)行身份驗(yàn)證來(lái)解決此問(wèn)題。

      所以 JWT 和 Session Cookies 的相同之處是什么?那就是它們能夠支持你在發(fā)送不同請(qǐng)求之間,記錄并驗(yàn)證你的登錄狀態(tài)的一種機(jī)制。

      什么是 Session Cookies

      Session Cookies 也稱為會(huì)話 Cookies,在 Session Cookies 中,用戶的登錄狀態(tài)會(huì)保存在服務(wù)器的內(nèi)存中。當(dāng)用戶登錄時(shí),Session 就被服務(wù)端安全的創(chuàng)建。

      在每次請(qǐng)求時(shí),服務(wù)器都會(huì)從會(huì)話 Cookie 中讀取 SessionId,如果服務(wù)端的數(shù)據(jù)和讀取的 SessionId 相同,那么服務(wù)器就會(huì)發(fā)送響應(yīng)給瀏覽器,允許用戶登錄。

      什么是 Json Web Tokens

      Json Web Token 的簡(jiǎn)稱就是 JWT,通常可以稱為 Json 令牌。它是RFC 7519 中定義的用于安全的將信息作為 Json 對(duì)象進(jìn)行傳輸?shù)囊环N形式。JWT 中存儲(chǔ)的信息是經(jīng)過(guò)數(shù)字簽名的,因此可以被信任和理解。可以使用 HMAC 算法或使用 RSA/ECDSA 的公用/專用密鑰對(duì) JWT 進(jìn)行簽名。

      使用 JWT 主要用來(lái)下面兩點(diǎn)

      認(rèn)證(Authorization):這是使用 JWT 最常見(jiàn)的一種情況,一旦用戶登錄,后面每個(gè)請(qǐng)求都會(huì)包含 JWT,從而允許用戶訪問(wèn)該令牌所允許的路由、服務(wù)和資源。單點(diǎn)登錄是當(dāng)今廣泛使用 JWT 的一項(xiàng)功能,因?yàn)樗拈_(kāi)銷很小。

      信息交換(Information Exchange):JWT 是能夠安全傳輸信息的一種方式。通過(guò)使用公鑰/私鑰對(duì) JWT 進(jìn)行簽名認(rèn)證。此外,由于簽名是使用 head 和 payload 計(jì)算的,因此你還可以驗(yàn)證內(nèi)容是否遭到篡改。

      下面,我們會(huì)探討一下 JWT 的組成和格式是什么

      JWT 主要由三部分組成,每個(gè)部分用 . 進(jìn)行分割,各個(gè)部分分別是

      Header

      Payload

      Signature

      因此,一個(gè)非常簡(jiǎn)單的 JWT 組成會(huì)是下面這樣

      然后我們分別對(duì)不同的部分進(jìn)行探討。

      Header

      Header 是 JWT 的標(biāo)頭,它通常由兩部分組成:令牌的類型(即 JWT)和使用的 簽名算法,例如 HMAC SHA256 或 RSA。

      例如

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

      1

      2

      3

      4

      指定類型和簽名算法后,Json 塊被 Base64Url 編碼形成 JWT 的第一部分。

      Payload

      Token 的第二部分是 Payload,Payload 中包含一個(gè)聲明。聲明是有關(guān)實(shí)體(通常是用戶)和其他數(shù)據(jù)的聲明。共有三種類型的聲明:registered, public 和 private 聲明。

      registered 聲明: 包含一組建議使用的預(yù)定義聲明,主要包括

      public 聲明:公共的聲明,可以添加任何的信息,一般添加用戶的相關(guān)信息或其他業(yè)務(wù)需要的必要信息,但不建議添加敏感信息,因?yàn)樵摬糠衷诳蛻舳丝山饷堋?/p>

      private 聲明:自定義聲明,旨在在同意使用它們的各方之間共享信息,既不是注冊(cè)聲明也不是公共聲明。

      例如

      { "sub": "1234567890", "name": "John Doe", "admin": true }

      1

      2

      3

      4

      5

      然后 payload Json 塊會(huì)被Base64Url 編碼形成 JWT 的第二部分。

      signature

      JWT 的第三部分是一個(gè)簽證信息,這個(gè)簽證信息由三部分組成

      header (base64后的)

      payload (base64后的)

      secret

      比如我們需要 HMAC SHA256 算法進(jìn)行簽名

      HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

      1

      2

      3

      4

      簽名用于驗(yàn)證消息在此過(guò)程中沒(méi)有更改,并且對(duì)于使用私鑰進(jìn)行簽名的令牌,它還可以驗(yàn)證 JWT 的發(fā)送者的真實(shí)身份

      現(xiàn)在我們把上面的三個(gè)由點(diǎn)分隔的 Base64-URL 字符串部分組成在一起,這個(gè)字符串可以在 HTML 和 HTTP 環(huán)境中輕松傳遞這些字符串。

      下面是一個(gè)完整的 JWT 示例,它對(duì) header 和 payload 進(jìn)行編碼,然后使用 signature 進(jìn)行簽名

      eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

      1

      如果想自己測(cè)試編寫(xiě)的話,可以訪問(wèn) JWT 官網(wǎng) https://jwt.io/#debugger-io

      JWT 和 Session Cookies 的不同

      JWT 和 Session Cookies 都提供安全的用戶身份驗(yàn)證,但是它們有以下幾點(diǎn)不同

      JWT 具有加密簽名,而 Session Cookies 則沒(méi)有。

      JWT 是無(wú)狀態(tài)的,因?yàn)槁暶鞅淮鎯?chǔ)在客戶端,而不是服務(wù)端內(nèi)存中。

      身份驗(yàn)證可以在本地進(jìn)行,而不是在請(qǐng)求必須通過(guò)服務(wù)器數(shù)據(jù)庫(kù)或類似位置中進(jìn)行。 這意味著可以對(duì)用戶進(jìn)行多次身份驗(yàn)證,而無(wú)需與站點(diǎn)或應(yīng)用程序的數(shù)據(jù)庫(kù)進(jìn)行通信,也無(wú)需在此過(guò)程中消耗大量資源。

      Session Cookies 是存儲(chǔ)在服務(wù)器內(nèi)存中,這就意味著如果網(wǎng)站或者應(yīng)用很大的情況下會(huì)耗費(fèi)大量的資源。由于 JWT 是無(wú)狀態(tài)的,在許多情況下,它們可以節(jié)省服務(wù)器資源。因此 JWT 要比 Session Cookies 具有更強(qiáng)的可擴(kuò)展性。

      Session Cookies 只能用在單個(gè)節(jié)點(diǎn)的域或者它的子域中有效。如果它們嘗試通過(guò)第三個(gè)節(jié)點(diǎn)訪問(wèn),就會(huì)被禁止。如果你希望自己的網(wǎng)站和其他站點(diǎn)建立安全連接時(shí),這是一個(gè)問(wèn)題。

      使用 JWT 可以解決這個(gè)問(wèn)題,使用 JWT 能夠通過(guò)多個(gè)節(jié)點(diǎn)進(jìn)行用戶認(rèn)證,也就是我們常說(shuō)的跨域認(rèn)證。

      JWT 和 Session Cookies 的選型

      我們上面探討了 JWT 和 Cookies 的不同點(diǎn),相信你也會(huì)對(duì)選型有了更深的認(rèn)識(shí),大致來(lái)說(shuō)

      對(duì)于只需要登錄用戶并訪問(wèn)存儲(chǔ)在站點(diǎn)數(shù)據(jù)庫(kù)中的一些信息的中小型網(wǎng)站來(lái)說(shuō),Session Cookies 通常就能滿足。

      如果你有企業(yè)級(jí)站點(diǎn),應(yīng)用程序或附近的站點(diǎn),并且需要處理大量的請(qǐng)求,尤其是第三方或很多第三方(包括位于不同域的API),則 JWT 顯然更適合。

      后記

      前兩天面試的時(shí)候問(wèn)到了這個(gè)題,所以寫(xiě)篇文章總結(jié)一下,還問(wèn)到了一個(gè)面試題,禁用 Cookies,如何使用 Session ?網(wǎng)上百度了一下,發(fā)現(xiàn)這是 PHP 的面試題…

      但還是選擇了解了一下,如何禁用 Cookies 后,使用 Session

      如果禁用了 Cookies,服務(wù)器仍會(huì)將 sessionId 以 cookie 的方式發(fā)送給瀏覽器,但是,瀏覽器不再保存這個(gè)cookie (即sessionId) 了。

      如果想要繼續(xù)使用 session,需要采用 URL 重寫(xiě) 的方式來(lái)實(shí)現(xiàn),可以參考 https://www.cnblogs.com/Renyi-Fan/p/11012086.html

      相關(guān)參考:

      https://www.cnblogs.com/Renyi-Fan/p/11012086.html

      https://blog.csdn.net/qq_28296925/article/details/80921585

      https://www.cnblogs.com/-ROCKS/p/6108556.html

      https://www.allaboutcookies.org/manage-cookies/

      https://www.jianshu.com/p/4a124a10fcaf

      https://tools.ietf.org/html/rfc7519

      https://jwt.io/introduction/

      https://wp-rocket.me/blog/browser-cache-vs-cookies-difference/

      https://wp-rocket.me/blog/difference-json-web-tokens-vs-session-cookies/

      HTTP 網(wǎng)絡(luò)

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:為什么你就不能加個(gè)空格呢?
      下一篇:兩列忠重復(fù)數(shù)據(jù)標(biāo)記(兩列找出重復(fù)數(shù)據(jù)標(biāo)紅)
      相關(guān)文章
      国产亚洲色视频在线| 久久精品国产亚洲av天美18| 亚洲午夜爱爱香蕉片| 人人狠狠综合久久亚洲| 亚洲日韩国产一区二区三区在线| 亚洲人成影院在线高清| 亚洲白色白色在线播放| 亚洲男人电影天堂| 亚洲国产成人无码av在线播放| 亚洲最大的视频网站| 亚洲日本国产精华液| 亚洲天堂电影在线观看| 亚洲精品成人图区| 亚洲av无码一区二区三区天堂古代 | 亚洲av成人一区二区三区在线观看| 亚洲av日韩专区在线观看| 亚洲欧美国产国产一区二区三区| 亚洲人AV在线无码影院观看| 亚洲午夜无码久久| 久久精品国产亚洲AV| 亚洲av无码天堂一区二区三区| 亚洲成在人线在线播放无码| 亚洲AV无码乱码在线观看代蜜桃 | 亚洲AV乱码一区二区三区林ゆな | 亚洲欧美自偷自拍另类视| 色天使亚洲综合在线观看| 亚洲人成色4444在线观看| 蜜芽亚洲av无码一区二区三区| 国产亚洲福利精品一区二区| 亚洲爆乳无码专区www| 亚洲国产精品狼友中文久久久| 国产成人+综合亚洲+天堂| 中文字幕无码精品亚洲资源网| 国产精品亚洲一区二区三区在线| 亚洲国产高清人在线| 中文字幕亚洲第一在线| 亚洲乱码在线视频| 久久久综合亚洲色一区二区三区| 亚洲综合在线成人一区| 亚洲成a人片7777| 亚洲av无码专区亚洲av不卡|