摘自透視HTTP協(xié)議:讓我知道你是誰:HTTP的Cookie機(jī)制
響應(yīng)頭字段 Set-Cookie
當(dāng)用戶通過瀏覽器第一次訪問服務(wù)器的時候,服務(wù)器肯定是不知道他的身份的慌随。所以,就要創(chuàng)建一個獨特的身份標(biāo)識數(shù)據(jù)介却,格式是key=value
楔绞,然后放進(jìn) Set-Cookie
字段里框喳,隨著響應(yīng)報文一同發(fā)給瀏覽器。
瀏覽器收到響應(yīng)報文锨并,看到里面有 Set-Cookie
露该,知道這是服務(wù)器給的身份標(biāo)識,于是就保存起來第煮,下次再請求的時候就自動把這個值放進(jìn) Cookie
字段里發(fā)給服務(wù)器抑党。
因為第二次請求里面有了 Cookie
字段底靠,服務(wù)器就知道這個用戶不是新人,之前來過鳄逾,就可以拿出 Cookie
里的值笆呆,識別出用戶的身份俄精,然后提供個性化的服務(wù)。
不過因為服務(wù)器的“記憶能力”實在是太差,所以,服務(wù)器有時會在響應(yīng)頭里添加多個 Set-Cookie
,存儲多個key=value
。
但瀏覽器這邊發(fā)送時不需要用多個 Cookie
字段,只要在一行里用“;”隔開就行角溃。
請求頭字段 Cookie
Cookie
就是服務(wù)器委托瀏覽器存儲在客戶端里的一些數(shù)據(jù),而這些數(shù)據(jù)通常都會記錄用戶的關(guān)鍵識別信息。所以纸型,就需要在key=value
外再用一些手段來保護(hù),防止外泄或竊取梅忌,這些手段就是 Cookie 的屬性
狰腌。
首先,我們應(yīng)該設(shè)置 Cookie 的生存周期
牧氮,即有效期
琼腔,可以使用 Expires
和 Max-Age
兩個屬性來設(shè)置。Expires
俗稱過期時間
踱葛,用絕對時間點
丹莲,可以理解為截止日期deadline
。Max-Age
用相對時間
尸诽,單位是秒甥材,瀏覽器用收到報文的時間點再加上 Max-Age
,就可以得到失效的絕對時間性含。它倆可以同時出現(xiàn)洲赵,兩者可一致,也可不一致胶滋,但瀏覽器會優(yōu)先采用 Max-Age
其次,我們需要設(shè)置 Cookie 的作用域
悲敷,讓瀏覽器僅發(fā)送給特定的服務(wù)器和 URI
究恤,避免被其他網(wǎng)站盜用。Domain
和Path
指定了 Cookie 所屬的域名和路徑
后德,瀏覽器在發(fā)送 Cookie
前會從 URI
中提取出 host
和 path
部分部宿,對比 ,如果不滿足條件,就不會在請求頭里發(fā)送 Cookie
理张。
最后要考慮的就是 Cookie 的安全性
了赫蛇,盡量不要讓服務(wù)器以外的人看到。寫過前端的同學(xué)一定知道雾叭,在 JS 腳本
里可以用 document.cookie
來讀寫 Cookie
數(shù)據(jù)悟耘,這就帶來了安全隱患,有可能會導(dǎo)致跨站腳本XSS
攻擊竊取數(shù)據(jù)织狐。屬性HttpOnly
會告訴瀏覽器暂幼,此 Cookie
只能通過瀏覽器 HTTP
協(xié)議傳輸,禁止其他方式訪問移迫,瀏覽器的 JS
引擎就會禁用 document.cookie
等一切相關(guān)的 API
旺嬉,腳本攻擊也就無從談起了。
另一個屬性SameSite
可以防范跨站請求偽造XSRF攻擊
厨埋,設(shè)置成SameSite=Strict
可以嚴(yán)格限定 Cookie
不能隨著跳轉(zhuǎn)鏈接跨站發(fā)送邪媳,而SameSite=Lax
則略寬松一點,允許GET/HEAD
等安全方法荡陷,但禁止 POST
跨站發(fā)送雨效。
還有一個屬性叫Secure
,表示這個 Cookie
僅能用 HTTPS
協(xié)議加密傳輸亲善,明文的 HTTP
協(xié)議會禁止發(fā)送设易。但 Cookie
本身不是加密的,瀏覽器里還是以明文的形式存在蛹头。
Chrome
開發(fā)者工具是查看 Cookie
的有力工具顿肺,在Network-Cookies
里可以看到單個頁面 Cookie
的各種屬性,另一個Application
面板里則能夠方便地看到全站的所有 Cookie
渣蜗。
Cookie 的應(yīng)用
Cookie 最基本的一個用途就是身份識別
屠尊,保存用戶的登錄信息,實現(xiàn)會話事務(wù)耕拷。比如讼昆,你用賬號和密碼登錄某電商,登錄成功后網(wǎng)站服務(wù)器就會發(fā)給瀏覽器一個 Cookie
骚烧,內(nèi)容大概是name=yourid
浸赫,這樣就成功地把身份標(biāo)簽貼在了你身上。之后你在網(wǎng)站里隨便訪問哪件商品的頁面赃绊,瀏覽器都會自動把身份 Cookie
發(fā)給服務(wù)器既峡,所以服務(wù)器總會知道你的身份,一方面免去了重復(fù)登錄的麻煩碧查,另一方面也能夠自動記錄你的瀏覽記錄和購物下單(在后臺數(shù)據(jù)庫或者也用 Cookie
)运敢,實現(xiàn)了狀態(tài)保持
校仑。
Cookie 的另一個常見用途是廣告跟蹤
。你上網(wǎng)的時候肯定看過很多的廣告圖片传惠,這些圖片背后都是廣告商網(wǎng)站(例如 Google
)迄沫,它會“偷偷地”給你貼上 Cookie
小紙條,這樣你上其他的網(wǎng)站卦方,別的廣告就能用 Cookie
讀出你的身份羊瘩,然后做行為分析,再推給你廣告愿汰。這種 Cookie
不是由訪問的主站存儲的困后,所以又叫第三方 Cookie(third-party cookie)
。如果廣告商勢力很大衬廷,廣告到處都是摇予,那么就比較“恐怖”了,無論你走到哪里它都會通過 Cookie
認(rèn)出你來吗跋,實現(xiàn)廣告“精準(zhǔn)打擊”侧戴。
為了防止濫用 Cookie
搜集用戶隱私,互聯(lián)網(wǎng)組織相繼提出了 DNT(Do Not Track)
和 P3P(Platform for Privacy Preferences Project)
跌宛,但實際作用不大酗宋。
jsessionid
什么時候生成并傳遞到前端的?
- 如果客戶端請求的
cookie
中不包含JSESSIONID
疆拘,服務(wù)端調(diào)用request.getSession()
時就會生成并傳遞給客戶端蜕猫,此次響應(yīng)頭會包含設(shè)置cookie
的信息
- 如果客戶端請求的
cookie
中包含JSESSIONID
,服務(wù)端調(diào)用request.getSession()
時就會根據(jù)JSESSIONID
進(jìn)行查找對象哎迄,如果能查到就返回回右,否則就跟沒傳遞JSESSIONID
一樣;
image.png