這次我們聊一下Cookie

邊緣煩惱發表於2019-03-26

這次我們聊一下Cookie
會話跟蹤技術用來跟蹤使用者的整個會話,會話就是使用者在登入網站後的一系列動作,常用的是Cookie和Session,兩者的唯一區別是前者在瀏覽器記錄資訊,後者在伺服器。今天只是簡單的說下Cookie,知道的就算看個熱鬧,不知道的希望能幫到你。

這次我們聊一下Cookie
以上圖片是我抓包得來,從上面的圖片可以看出,cookie中的值是key-value格式的,而且是通過一個分號和空格來間隔的。

cookie的流程是:伺服器設定cookie---通過response將cookie傳到前端儲存在瀏覽器中---前端訪問後端介面時在request header中自動新增上cookie---服務端接收到cookie做一些業務操作。

那麼cookie是怎麼工作的呢?首先cookie對於瀏覽器來說只是一個純文字,瀏覽器的安裝目錄下是會有一個專門的資料夾用來儲存各個網站的cookie。當從前端傳送請求到後端的時候,瀏覽器會自動的檢測下是否有cookie,如果有就會新增到請求的頭資訊中,以上是瀏覽器自動幫我們做的。

儲存到cookie中的資料,瀏覽器會自動的放在http請求中,只有是每次請求都必須要傳送給伺服器的資料才會放到cookie,比如身份驗證資訊。如果是不必要的,必然會增加網路開銷。針對這個儲存資訊大小,cookie還是做了一些限制的。每個域名下的cookie 的大小最大為4KB,每個域名下的cookie數量最多為20個(但很多瀏覽器廠商在具體實現時支援大於20個)。

cookie的屬性包括:過期時間;域名、路徑等等,這些可以自己設定,如果不手動設定就會使用cookie的預設設定。

expires

過期時間,expires必須是 GMT 格式的時間(可以通過new Date().toGMTString()或者 new Date().toUTCString() 來獲得)。

如果沒有設定的話,那麼預設的有效期就是session,就是會話cookie,這種會在瀏覽器關掉的時候就沒有了。

domain和path

domain是域名,path是路徑,兩者組合起來就構成了 URL,domain和path一起來限制 cookie 能被哪些 URL 訪問。

就是說在訪問這個域名或者是該域名的子域名下,目錄是在該目錄或者是在該目錄下的子目錄下的時候,瀏覽器會自動把cookie放到請求頭部中。

如果沒有設定這兩個選項,則會使用預設值。domain的預設值為設定該cookie的網頁所在的域名,path預設值為設定該cookie的網頁所在的目錄。

兩點需要注意:domain可以設定為頁面本身的域名,或者是該域名的父域名,比如說,www.sougou.com,可是設定為www.sougou.com,也可以設定為sougou.com。

secure

secure選項用來設定cookie只在確保安全的請求中才會傳送。當請求是HTTPS或者其他安全協議時,包含 secure 選項的 cookie才能被髮送至伺服器。

預設情況下,cookie不會帶secure選項(即為空)。所以預設情況下,不管是HTTPS協議還是HTTP協議的請求,cookie 都會被髮送至服務端。但要注意一點,secure選項只是限定了在安全情況下才可以傳輸給服務端,但並不代表你不能看到這個 cookie。

httpOnly

這個選項用來設定cookie是否能通過 js 去訪問。預設情況下,cookie不會帶httpOnly選項(即為空),所以預設情況下,客戶端是可以通過js程式碼去訪問(包括讀取、修改、刪除等)這個cookie的。當cookie帶httpOnly選項時,客戶端則無法通過js程式碼去訪問操作(包括讀取、修改、刪除等)這個cookie。

在客戶端是不能通過js程式碼去設定一個httpOnly型別的cookie的,這種型別的cookie只能通過服務端來設定。

關於限制客戶端去訪問cookie的問題,這樣做的目的就是為了保證安全。

試想:如果任何 cookie 都能被客戶端通過document.cookie獲取會發生什麼。當我們的網頁遭受了 XSS 攻擊,有一段惡意的script指令碼插到了網頁中。這段script指令碼做的事情是:通過document.cookie讀取了使用者身份驗證相關的 cookie,並將這些 cookie 傳送到了攻擊者的伺服器。攻擊者輕而易舉就拿到了使用者身份驗證資訊,於是就可以利用此使用者資訊訪問目標伺服器(因為攻擊者有合法的使用者身份驗證資訊,所以會通過你伺服器的驗證)。

下面的這段是從專案中找到的一段關於設定cookie的程式碼:

public void addCookie(HttpServletResponse response, String cookieValue) {
       if (this.cookieDomain == null) {
           throw new IllegalArgumentException("cookies domain is not null");
       } else {
           Cookie cookie = new Cookie(this.coookieName, cookieValue);
           cookie.setPath(this.cookiePath);
           if (this.cookieDomain != null) {
               cookie.setDomain(this.cookieDomain);
           }

           if (this.cookieMaxAge != null) {
               cookie.setMaxAge(this.cookieMaxAge);
           }

           if (this.cookieSecure) {
               cookie.setSecure(true);
           }

           if (this.cookieHttpOnly) {
               cookie.setHttpOnly(true);
           }

           response.addCookie(cookie);
       }
   }
複製程式碼

什麼時候 cookie 會被覆蓋:cookie中的name、domain、path 這3個欄位數值都相同的時候。

如果顯式設定了 domain,則設定成什麼,瀏覽器就存成什麼;但如果沒有顯式設定,則瀏覽器會自動取 url 的 host 作為 domain 值;

修改 cookie。

要想修改一個cookie,只需要重新賦值就行,舊的值會被新的值覆蓋。但要注意一點,在設定新cookie時,path、domain這兩個欄位一定要和之前保持一樣。否則是不會確定為之前的cookie,而是新增了一個新的cookie。

刪除 cookie

刪除一個cookie 也是一樣的,也是重新賦值,只要將這個新cookie的expires選項設定為一個過去的時間點或者是直接賦值為0就行了。但同樣要注意,path和domain同樣需要和之前的cookie保持一致。

在開發的過程中,使用者的登入態是大部分是放到cookie裡,因為cookie自己有著完整的一套配置,包括上文講到的各種屬性和安全問題,總體來說還是比較方便的。

東西不多,也很簡單,希望每個讀者都能完全消化。

這樣的分享會一直持續,你的關注、轉發和好看是對我最大的支援,感謝。

關注公眾號,最新文章會第一時間出現在那裡哦!

這次我們聊一下Cookie

相關文章