Web Cookie

Web Cookie

什麼是Cookie

Cookie是服務器在瀏覽器保存的一小段文本信息,每個 Cookie 的大小一般不能超過4KB。服務器根據需要通過HTTP Response Headers的Set-Cookie來設置瀏覽器的Cookie,之後瀏覽器在向服務器發送請求,就會在HTTP Request Headers的Cookie中帶此域名下的Cookie值。我們最常見的Cookie的作用是和服務器端的session結合使用,來在HTTP協議中保存登錄後用戶的信息。

我們總是說:“當我們在瀏覽器打開一個網站,就和這個網站建立了會話”。其實這句話的本質是:服務器給瀏覽器的響應中,向瀏覽器寫入了一個Cookie,這個Cookie的值就session id,這個id用來標識服務器端的一個對象,這個對象就是session對象。

我又總是說:“當我們關閉一個網站,會話結束了,當你再次打開這個網站,會和服務器建立一個新的會話”。這句話的本質是:服務器設置的Cookie生命週期是會話週期,即關閉網站的所有窗口和tab頁會話結束,Cookie也就結束了,這個時候服務器的session對象還是存在的,只不過服務器有機制保證session對象在一定的時間未被使用或訪問就會銷燬這個session對象。當我們在此訪問網站,發送第一個請求的時候,服務器的響應一個新的Cookie,即一個新的 session id。

Cookie的格式和屬性

通過HTTP Response Headers的Set-Cookie來在瀏覽器寫入Cookie時,此Cookie的格式的每個屬性以分號";"進行分割。

Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]

實際Cookie示例

Set-Cookie:name=zhangxy; Max-Age=86400; Expires=Thu, 12-Sep-2019 03:21:38 GMT; Domain=localhost; Path=/; HttpOnly

value屬性
此屬性是必須的,它是一個鍵值對,格式爲value=key。上面的示例中key爲name,value爲zhangxy。
expires屬性
expires屬性用於指定Cookie過期時間。它的格式採用Date.toUTCString()的格式。
如果不設置該屬性,或者設爲nul表示Cookie只在當前會話(session)有效,網站的所有窗口或tab頁都關閉當前Session就結束了,此時該Cookie就會被刪除。如果設置爲負數,表明刪除該Cookie。如果設置爲一個符合格式的時間,表明Cookie的過期時間,瀏覽器根據本地時間,決定Cookie是否過期,由於本地時間是不精確的,所以沒有辦法保證Cookie一定會在服務器指定的時間過期。

max-age
max-age屬性用來指定Cookie有效期,單位是秒,設置爲正整數爲Cookie的有效期,設置爲負數表示只在當前會話下有效,設置爲0表示刪除此Cookie,作用等同於expires屬性。
max-age是通過設置從現在算起到設置的多少秒之內Cookie有效,expires是通過指定一個時間點,過了這個時間點Cookie失效。比如,當前設置Cookie的max-age屬性爲60 * 60 * 24 * 365(即一年),當前設置Cookie的時間爲2019-09-11,那麼此Cookie的到期時間爲2020-09-11。和expires設置爲2020-09-11效果等同。

expires和max-age屬性是設置了Cookie的生命週期,根據生命週期Cookie可以分爲內存Cookie和持久化Cookie,前者session結束Cookie也就消失了,後者是即使網站所有tab也關閉了,Cookie信息會寫入磁盤,下次在訪問此網站,Cookie依然是有效的,直到指定的時間纔會失效。

domain屬性
指定Cookie所在的域名,比如example.com或.example.com(這種寫法將對所有子域名生效)、subdomain.example.com。
如果未指定,默認爲設定該Cookie的域名。所指定的域名必須是當前發送Cookie的域名的一部分,比如當前訪問的域名是example.com,就不能將其設爲google.com。只有訪問的域名匹配domain屬性,Cookie纔會發送到服務器。

path 屬性
path屬性用來指定路徑,必須是絕對路徑(比如/、/mydir),如果未指定,默認爲請求該 Cookie 的網頁路徑。
只有path屬性匹配向服務器發送的路徑,Cookie 纔會發送。這裏的匹配不是絕對匹配,而是從根路徑開始,只要path屬性匹配發送路徑的一部分,就可以發送。比如,path屬性等於/blog,則發送路徑是/blog或者/blog/roll,Cookie都會發送。path屬性生效的前提是domain屬性匹配。

*從domain和path屬性可以看出如果需要網站接受Cookie,兩個屬性必須匹配當前URL路徑。例如,當前URL爲http://baidu.com/a,那麼domain爲baidu.com,path爲/a(或/a的子路徑),此Cookie 纔會生效。

secure 屬性
secure屬性用來指定Cookie只能在加密協議HTTPS下發送到服務器。

HttpOnly屬性
設置該Cookie不能被JavaScript讀取。通過document.cookie不會返回設置HttpOnly屬性的Cookie,即使進行AJAX操作時,XMLHttpRequest對象也無法包括這個Cookie。這主要是爲了防止XSS攻擊盜取Cookie。注意:XMLHttpRequest對象和js無法讀取,不代表瀏覽器本身不可以,設置了HttpOnly屬性的Cookie還是會包含在Request Headers中的。

Cookie的應用場景

我能想到的就兩個:

  1. 在Cookie中存儲JSESSIONID,用於與服務器端的session對象建立聯繫。
  2. 在Cookie中存儲用戶名和密碼(應該是加密後的密碼),用於用戶打開登錄頁面自動登錄系統。

JavaScript中的Cookie對象

通過document.cookie來操作Cookie對象。不做詳解,有興趣百度。

Java中的Cookie對象

Java中通過javax.servlet.http.Cookie來創建一個Cookie對象,通過response.addCookie來向響應中添加一個Cookie對象。

向瀏覽器中添加名爲lsmsAppService-JWT-token的Cookie

//lsmsAppService-JWT-token是value屬性的key部分
//token是value屬性的value部分
Cookie cookie = new Cookie("lsmsAppService-JWT-token", "token");
cookie.setMaxAge(-1);	//聲明週期爲會話聲明週期
cookie.setDomain("localhost"); 		//域名爲localhost
cookie.setPath("/");		//設置路徑
cookie.setHttpOnly(true); 	//設置瀏覽器端JS無法讀取此Cookie
response.addCookie(cookie);

在瀏覽器中刪除名爲lsmsAppService-JWT-token的Cookie

Cookie cookie = new Cookie("lsmsAppService-JWT-token", "");
cookie.setDomain("localhost");
cookie.setPath("/");
cookie.setMaxAge(0); //0標識在瀏覽器中刪除此Cookie
response.addCookie(cookie);

在瀏覽器中更新名爲lsmsAppService-JWT-token的Cookie

Cookie cookie = new Cookie("lsmsAppService-JWT-token", "JWT-token");
cookie.setDomain("localhost");		//同創建lsmsAppService-JWT-token Cookie時的domain值一樣
cookie.setPath("/");		//同創建lsmsAppService-JWT-token Cookie時的path值一樣
cookie.setMaxAge(60*60*24);
response.addCookie(cookie);

注意:向瀏覽器寫入Cookie時設置的value、domain、path和secure會作爲此Cookie的唯一標識,在刪除或修改此Cookie時,會匹配創建Cookie時設置的value、domain、path和secure。

參考資料:
https://m.w3cschool.cn/javascript_guide/javascript_guide-yfck269z.html
https://www.cnblogs.com/mao2080/p/9520185.html
https://www.cnblogs.com/bq-med/p/8603664.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章