2 月份發佈的 Chrome 80 版本中默認屏蔽了第三方的 Cookie,在灰度期間,就致使了阿里系的不少應用都產生了問題,爲此還專門成立了小組,推進各 BU 進行改造,目前阿里系基本已經改造完成。全部的前端團隊估計都收到過通知,也着實加深了一把你們對於 Cookie 的理解,因此極可能就此出個面試題,而即使不是面試題,當問到 HTTP 相關內容的時候,不妨也扯到這件事情來,一能代表你對前端時事的跟進,二還能借此引伸到前端安全方面的內容,爲你的面試加分。前端
因此本文就給你們介紹一下瀏覽器的 Cookie 以及這個"火熱"的 SameSite 屬性。git
通常咱們都會說 「HTTP 是一個無狀態的協議」,不過要注意這裏的 HTTP 實際上是指 HTTP 1.x,而所謂無狀態協議,簡單的理解就是即便同一個客戶端連續兩次發送請求給服務器,服務器也識別不出這是同一個客戶端發送的請求,這致使的問題就好比你加了一個商品到購物車中,但由於識別不出是同一個客戶端,你刷新下頁面就沒有了……github
爲了解決 HTTP 無狀態致使的問題,後來出現了 Cookie。不過這樣說可能會讓你產生一些誤解,首先無狀態並非很差,有優勢,但也會致使一些問題。而 Cookie 的存在也不是爲了解決通信協議無狀態的問題,只是爲了解決客戶端與服務端會話狀態的問題,這個狀態是指後端服務的狀態而非通信協議的狀態。web
那咱們來看下 Cookie,引用下維基百科:面試
Cookie(複數形態Cookies),類型爲「小型文本文件」,指某些網站爲了辨別用戶身份而儲存在用戶本地終端上的數據。
做爲一段通常不超過 4KB 的小型文本數據,它由一個名稱(Name)、一個值(Value)和其它幾個用於控制 Cookie 有效期、安全性、使用範圍的可選屬性組成,這些涉及的屬性咱們會在後面會介紹。sql
咱們能夠在瀏覽器的開發者工具中查看到當前頁面的 Cookie:數據庫
儘管咱們在瀏覽器裏查看到了 Cookie,這並不意味着 Cookie 文件只是存放在瀏覽器裏的。實際上,Cookies 相關的內容還能夠存在本地文件裏,就好比說 Mac 下的 Chrome,存放目錄就是~/Library/Application Support/Google/Chrome/Default
,裏面會有一個名爲 Cookies 的數據庫文件,你可使用 sqlite 軟件打開它:json
存放在本地的好處就在於即便你關閉了瀏覽器,Cookie 依然能夠生效。後端
那 Cookie 是怎麼設置的呢?簡單來講就是跨域
咱們以https://main.m.taobao.com/
爲例來看下這個過程:
咱們在請求返回的 Response Headers 能夠看到 Set-Cookie 字段:
而後咱們查看下 Cookie:
咱們刷新一遍頁面,再看下這個請求,能夠在 Request Headers 看到 cookie 字段:
在下面這張圖裏咱們能夠看到 Cookies 相關的一些屬性:
這裏主要說一些你們可能沒有注意的點:
用 JavaScript 操做 Cookie 的時候注意對 Value 進行編碼處理。
Expires 用於設置 Cookie 的過時時間。好比:
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
當 Expires 屬性缺省時,表示是會話性 Cookie,像上圖 Expires 的值爲 Session,表示的就是會話性 Cookie。當爲會話性 Cookie 的時候,值保存在客戶端內存中,並在用戶關閉瀏覽器時失效。須要注意的是,有些瀏覽器提供了會話恢復功能,這種狀況下即便關閉了瀏覽器,會話期 Cookie 也會被保留下來,就好像瀏覽器歷來沒有關閉同樣。
與會話性 Cookie 相對的是持久性 Cookie,持久性 Cookies 會保存在用戶的硬盤中,直至過時或者清除 Cookie。這裏值得注意的是,設定的日期和時間只與客戶端相關,而不是服務端。
Max-Age 用於設置在 Cookie 失效以前須要通過的秒數。好比:
Set-Cookie: id=a3fWa; Max-Age=604800;
Max-Age 能夠爲正數、負數、甚至是 0。
若是 max-Age 屬性爲正數時,瀏覽器會將其持久化,即寫到對應的 Cookie 文件中。
當 max-Age 屬性爲負數,則表示該 Cookie 只是一個會話性 Cookie。
當 max-Age 爲 0 時,則會當即刪除這個 Cookie。
假如 Expires 和 Max-Age 都存在,Max-Age 優先級更高。
Domain 指定了 Cookie 能夠送達的主機名。假如沒有指定,那麼默認值爲當前文檔訪問地址中的主機部分(可是不包含子域名)。
像淘寶首頁設置的 Domain 就是 .taobao.com,這樣不管是a.taobao.com仍是b.taobao.com均可以使用 Cookie。
在這裏注意的是,不能跨域設置 Cookie,好比阿里域名下的頁面把 Domain 設置成百度是無效的:
Set-Cookie: qwerty=219ffwef9w0f; Domain=baidu.com; Path=/; Expires=Wed, 30 Aug 2020 00:00:00 GMT
Path 指定了一個 URL 路徑,這個路徑必須出如今要請求的資源的路徑中才能夠發送 Cookie 首部。好比設置Path=/docs
,/docs/Web/
下的資源會帶 Cookie 首部,/test
則不會攜帶 Cookie 首部。
Domain 和 Path 標識共同定義了 Cookie 的做用域:即 Cookie 應該發送給哪些 URL。
標記爲 Secure 的 Cookie 只應經過被HTTPS協議加密過的請求發送給服務端。使用 HTTPS 安全協議,能夠保護 Cookie 在瀏覽器和 Web 服務器間的傳輸過程當中不被竊取和篡改。
設置 HTTPOnly 屬性能夠防止客戶端腳本經過 document.cookie 等方式訪問 Cookie,有助於避免 XSS 攻擊。
SameSite 是最近很是值得一提的內容,由於 2 月份發佈的 Chrome80 版本中默認屏蔽了第三方的 Cookie,這會致使阿里系的不少應用都產生問題,爲此還專門成立了問題小組,推進各 BU 進行改造。
咱們先來看看這個屬性的做用:
SameSite 屬性可讓 Cookie 在跨站請求時不會被髮送,從而能夠阻止跨站請求僞造攻擊(CSRF)。
SameSite 能夠有下面三種值:
以前默認是 None 的,Chrome80 後默認是 Lax。
首先要理解的一點就是跨站和跨域是不一樣的。同站(same-site)/跨站(cross-site)」和第一方(first-party)/第三方(third-party)是等價的。可是與瀏覽器同源策略(SOP)中的「同源(same-origin)/跨域(cross-origin)」是徹底不一樣的概念。
同源策略的同源是指兩個 URL 的協議/主機名/端口一致。例如,https://www.taobao.com/pages/...,它的協議是 https,主機名是www.taobao.com,端口是 443。
同源策略做爲瀏覽器的安全基石,其「同源」判斷是比較嚴格的,相對而言,Cookie中的「同站」判斷就比較寬鬆:只要兩個 URL 的 eTLD+1 相同便可,不須要考慮協議和端口。其中,eTLD 表示有效頂級域名,註冊於 Mozilla 維護的公共後綴列表(Public Suffix List)中,例如,.com、.co.uk、.github.io 等。eTLD+1 則表示,有效頂級域名+二級域名,例如taobao.com等。
舉幾個例子,www.taobao.com和www.baidu.com是跨站,www.a.taobao.com和www.b.taobao.com是同站,a.github.io和b.github.io是跨站(注意是跨站)。
接下來看下從 None 改爲 Lax 到底影響了哪些地方的 Cookies 的發送?直接來一個圖表:
從上圖能夠看出,對大部分 web 應用而言,Post 表單,iframe,AJAX,Image 這四種狀況從之前的跨站會發送三方 Cookie,變成了不發送。
Post表單:應該的,學 CSRF 總會舉表單的例子。
iframe:iframe 嵌入的 web 應用有不少是跨站的,都會受到影響。
AJAX:可能會影響部分前端取值的行爲和結果。
Image:圖片通常放 CDN,大部分狀況不須要 Cookie,故影響有限。但若是引用了須要鑑權的圖片,可能會受到影響。
除了這些還有 script 的方式,這種方式也不會發送 Cookie,像淘寶的大部分請求都是 jsonp,若是涉及到跨站也有可能會被影響。
咱們再看看會出現什麼的問題?舉幾個例子:
若是不解決,影響的系統其實仍是不少的……
解決方案就是設置 SameSite 爲 none。
以 Adobe 網站爲例:https://www.adobe.com/sea/,查看請求能夠看到:
不過也會有兩點要注意的地方:
若是你想加 SameSite=none 屬性,那麼該 Cookie 就必須同時加上 Secure 屬性,表示只有在 HTTPS 協議下該 Cookie 纔會被髮送。
IOS 12 的 Safari 以及老版本的一些 Chrome 會把 SameSite=none 識別成 SameSite=Strict,因此服務端必須在下發 Set-Cookie 響應頭時進行 User-Agent 檢測,對這些瀏覽器不下發 SameSite=none 屬性
Cookie 主要用於如下三個方面:
若是被問到話,能夠從大小、安全、增長請求大小等方面回答。
各類系列文章目錄地址:https://github.com/mqyqingfeng/Blog
若是有錯誤或者不嚴謹的地方,請務必給予指正,十分感謝。若是喜歡或者 有所啓發,歡迎 star,對做者也是一種鼓勵。
21屆(大三或者研二)的同窗,要不要加入面試內推衝刺互助羣?各類福利活動,一對一簡歷輔導、各類進階指南、面試經驗、你說出你的面試題,還有淘系前端幫你寫答案 (是真的😂),歡迎掃碼入羣,買不了吃虧,買不了上當