什么是Cookie
HTTP協(xié)議本身是無(wú)狀態(tài)的。什么是無(wú)狀態(tài)呢释涛,即服務(wù)器無(wú)法判斷用戶(hù)身份侮攀。Cookie實(shí)際上是一小段的文本信息(key-value格式)∮保客戶(hù)端向服務(wù)器發(fā)起請(qǐng)求拴鸵,如果服務(wù)器需要記錄該用戶(hù)狀態(tài),就使用response向客戶(hù)端瀏覽器頒發(fā)一個(gè)Cookie蜗搔【⒚辏客戶(hù)端瀏覽器會(huì)把Cookie保存起來(lái)。當(dāng)瀏覽器再請(qǐng)求該網(wǎng)站時(shí)樟凄,瀏覽器把請(qǐng)求的網(wǎng)址連同該Cookie一同提交給服務(wù)器聘芜。服務(wù)器檢查該Cookie,以此來(lái)辨認(rèn)用戶(hù)狀態(tài)缝龄。
第一方cookie和第三方cookie
第一方cookie
第一方 cookie 指的是由網(wǎng)絡(luò)用戶(hù)訪(fǎng)問(wèn)的域創(chuàng)建的 cookie汰现。例如:當(dāng)用戶(hù)通過(guò)網(wǎng)絡(luò)瀏覽器點(diǎn)擊簡(jiǎn)書(shū)jianshu.com時(shí),瀏覽器會(huì)在第一個(gè)頁(yè)面中發(fā)送一個(gè)網(wǎng)頁(yè)請(qǐng)求叔壤,這個(gè)過(guò)程需要用戶(hù)直接與 jianshu.com 互動(dòng)例如登錄什么的瞎饲。這樣網(wǎng)絡(luò)瀏覽器隨后就將此數(shù)據(jù)文件保存到j(luò)ianshu.com域名下的用戶(hù)計(jì)算機(jī)上。
第三方cookie
第三方cookie是建立在別的域名不是你訪(fǎng)問(wèn)的域名(地址欄中的網(wǎng)址)炼绘, 比如:廣告網(wǎng)絡(luò)商就是最常見(jiàn)的第三方 cookies 的來(lái)源嗅战,他們用它們?cè)诙鄠€(gè)網(wǎng)站上追蹤用戶(hù)的行為,當(dāng)然這些活動(dòng)可以用來(lái)調(diào)整廣告俺亮。此外圖像驮捍、 JavaScript 和 iframe 通常也會(huì)導(dǎo)致第三方 cookies 的生成形庭。
解釋一下廣告是如何精準(zhǔn)投放的。首先我們所看到的廣告都是由一些互聯(lián)網(wǎng)巨頭集合中小網(wǎng)絡(luò)媒體資源厌漂,通過(guò)聯(lián)盟平臺(tái)幫助廣告主實(shí)現(xiàn)廣告投放,并進(jìn)行數(shù)據(jù)監(jiān)測(cè)統(tǒng)計(jì)斟珊,當(dāng)你的網(wǎng)站或博客有一定的流量時(shí)可以去這些廣告聯(lián)盟官網(wǎng)進(jìn)行申請(qǐng)苇倡。以百度聯(lián)盟為例:使用百度的時(shí)候,會(huì)把你的此次搜索保存到cookie中囤踩,并且分配這個(gè)瀏覽器唯一可標(biāo)識(shí)的ID號(hào)旨椒,當(dāng)打開(kāi)人人影視的時(shí)候,該頁(yè)的廣告模塊就向第三方也就是廣告服務(wù)商的服務(wù)器去請(qǐng)求百度保存在瀏覽器的cookie堵漱,然后就可以知道你最近瀏覽或者搜索過(guò)哪些商品综慎,然后就返回給你相關(guān)的廣告。
Cookie的查看
我們可以在瀏覽器的開(kāi)發(fā)者工具中查看到當(dāng)前頁(yè)面的 Cookie:
Cookie的設(shè)置
1勤庐、客戶(hù)端發(fā)送 HTTP 請(qǐng)求到服務(wù)器
2示惊、當(dāng)服務(wù)器收到 HTTP 請(qǐng)求時(shí),在響應(yīng)頭里面添加一個(gè) Set-Cookie 字段
3愉镰、瀏覽器收到響應(yīng)后保存下 Cookie
4米罚、之后對(duì)該服務(wù)器每一次請(qǐng)求中都通過(guò) Cookie 字段將 Cookie 信息發(fā)送給服務(wù)器。
我通過(guò)post請(qǐng)求一個(gè)登錄接口丈探,并在登錄接口中在響應(yīng)頭里面添加一個(gè) Set-Cookie 字段
我們?cè)谡?qǐng)求返回的 Response Headers 可以看到 Set-Cookie 字段:和Request Headers 看到 cookie 字段(Response Headers和Request Headers 的作用和區(qū)別待補(bǔ)充)
當(dāng)我們?cè)僬{(diào)用這個(gè)服務(wù)器上的另外一個(gè)接口時(shí)我們就可以很輕松的拿到這個(gè)cookie值
我們就可以通過(guò)獲取的cookie對(duì)登錄用戶(hù)進(jìn)行再次驗(yàn)證录择,通過(guò)其cookie中的信息跳轉(zhuǎn)不同的頁(yè)面。
這里提一下前端是只能讀取在前端的cookie而后臺(tái)設(shè)置的cookie只有在同域的情況下才能讀取到碗降。
Cookie的屬性
Name/Value
鍵值對(duì)隘竭,可以設(shè)置要保存的 Key/Value,注意這里的 NAME 不能和其他屬性項(xiàng)的名字一樣
Expires
過(guò)期時(shí)間讼渊,在設(shè)置的某個(gè)時(shí)間點(diǎn)后該 Cookie 就會(huì)失效动看。Cookie中的maxAge用來(lái)表示該屬性,單位為秒爪幻。maxAge有3種值弧圆,分別為正數(shù),負(fù)數(shù)和0笔咽。
如果maxAge屬性為正數(shù)搔预,則表示該Cookie會(huì)在maxAge秒之后自動(dòng)失效。瀏覽器會(huì)將maxAge為正數(shù)的Cookie持久化叶组,即寫(xiě)到對(duì)應(yīng)的Cookie文件中(每個(gè)瀏覽器存儲(chǔ)的位置不一致)拯田。無(wú)論客戶(hù)關(guān)閉了瀏覽器還是電腦,只要還在maxAge秒之前甩十,登錄網(wǎng)站時(shí)該Cookie仍然有效船庇。當(dāng)為0時(shí)表示立即刪除cookie吭产。為負(fù)數(shù)時(shí)到期時(shí)間為創(chuàng)建時(shí)間之前。運(yùn)行窗口關(guān)閉后會(huì)銷(xiāo)毀時(shí)間到期的cookie鸭轮。
Domain
Domain 指定了 Cookie 可以送達(dá)的主機(jī)名臣淤。假如沒(méi)有指定,那么默認(rèn)值為當(dāng)前文檔訪(fǎng)問(wèn)地址中的主機(jī)部分(但是不包含子域名)窃爷。但不能將一個(gè)cookie的域設(shè)置成服務(wù)器所在的域之外的域邑蒋。是無(wú)效的。
Path
Path 指定了一個(gè) URL 路徑按厘,這個(gè)路徑必須出現(xiàn)在要請(qǐng)求的資源的路徑中才可以發(fā)送 Cookie 首部医吊。設(shè)置為"/"表示允許所有路徑都可以使用Cookie,
Domain 和 Path 標(biāo)識(shí)共同定義了 Cookie 的作用域:即 Cookie 應(yīng)該發(fā)送給哪些 URL逮京。
Secure
標(biāo)記為 Secure 的 Cookie 只應(yīng)通過(guò)被HTTPS協(xié)議加密過(guò)的請(qǐng)求發(fā)送給服務(wù)端卿堂。使用 HTTPS 安全協(xié)議酷窥,可以保護(hù) Cookie 在瀏覽器和 Web 服務(wù)器間的傳輸過(guò)程中不被竊取和篡改履澳。
HTTPOnly
設(shè)置 HTTPOnly 屬性可以防止客戶(hù)端腳本通過(guò) document.cookie 等方式訪(fǎng)問(wèn) Cookie,有助于避免 XSS 攻擊慌洪。
SameSite
SameSite 也是這篇博客的主體策严,首先我們來(lái)看看這個(gè)參數(shù)的作用陶珠。
SameSite 屬性可以讓 Cookie 在跨站請(qǐng)求時(shí)不會(huì)被發(fā)送,從而可以阻止跨站請(qǐng)求偽造攻擊(CSRF)享钞。至于什么是CSRF這里就不具體說(shuō)了揍诽。
SameSite 可以有下面三種值:
1、Strict僅允許一方請(qǐng)求攜帶 Cookie栗竖,即瀏覽器將只發(fā)送相同站點(diǎn)請(qǐng)求的 Cookie暑脆,即當(dāng)前網(wǎng)頁(yè) URL 與請(qǐng)求目標(biāo) URL 完全一致。
2狐肢、Lax允許部分第三方請(qǐng)求攜帶 Cookie
3添吗、None無(wú)論是否跨站都會(huì)發(fā)送 Cookie
造成現(xiàn)在無(wú)法獲取cookie是因?yàn)橹澳J(rèn)是 None 的,Chrome80 后默認(rèn)是 Lax份名。
跨域和跨站
首先要理解的一點(diǎn)就是跨站和跨域是不同的碟联。同站(same-site)/跨站(cross-site)」和第一方(first-party)/第三方(third-party)是等價(jià)的。但是與瀏覽器同源策略(SOP)中的「同源(same-origin)/跨域(cross-origin)」是完全不同的概念僵腺。
同源策略的同源是指兩個(gè) URL 的協(xié)議/主機(jī)名/端口一致鲤孵。例如https://127.0.0.1:8000/它的協(xié)議是 https,主機(jī)名是127.0.0.1辰如,端口是 8000普监。
同源策略作為瀏覽器的安全基石,其「同源」判斷是比較嚴(yán)格的,相對(duì)而言凯正,Cookie中的「同站」判斷就比較寬松:只要兩個(gè) URL 的 eTLD+1 相同即可毙玻,不需要考慮協(xié)議和端口。其中廊散,eTLD 表示有效頂級(jí)域名桑滩,注冊(cè)于 Mozilla 維護(hù)的公共后綴列表(Public Suffix List)中,例如允睹,.com运准、.co.uk、.github.io 等擂找。eTLD+1 則表示,有效頂級(jí)域名+二級(jí)域名浩销,例如taobao.com等贯涎。這部分內(nèi)容還需要再補(bǔ)充。
改變
來(lái)看下從 None 改成 Lax 到底影響了哪些地方的 Cookies 的發(fā)送慢洋。
從上圖可以看出塘雳,對(duì)大部分 web 應(yīng)用而言,Post 表單普筹,iframe败明,AJAX,Image 這四種情況從以前的跨站會(huì)發(fā)送三方 Cookie太防,變成了不發(fā)送妻顶。故這四種情況跨站給第三方發(fā)送 Cookie需要在設(shè)置的時(shí)候?qū)ameSite設(shè)置為None。
谷歌瀏覽器中對(duì)第三方的cookie設(shè)置
SameSite by default cookies
把這個(gè)設(shè)置關(guān)了就允許所有的第三方cookie
Cookies without SameSite must be secure
這個(gè)設(shè)置就是所謂的許多博客提到的http設(shè)置SameSite=None無(wú)效必須設(shè)置Secure的原因蜒车。如果把這個(gè)設(shè)置設(shè)置為Disabled讳嘱,那么http設(shè)置SameSite=None是有效的。
Enable removing SameSite=None cookies
這個(gè)是關(guān)于第三方cookie是否可以在谷歌設(shè)置中chrome://settings/siteData單獨(dú)刪除第三方cookie酿愧。