數(shù)據(jù)庫(kù)】">保姆級(jí)Mysql讀寫(xiě)鎖圖文教程丨【綻放吧!數(shù)據(jù)庫(kù)】
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 如何判斷是否是同一會(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)容。