關(guān)鍵詞:cookie 安全性 GDPR
可能你最近在訪問一些在歐洲有業(yè)務(wù)來往的網(wǎng)站的時候,你會發(fā)現(xiàn)會有Cookie的提示,沒錯,最近歐盟GDPR生效,前陣子一直忙于Cookie Privacy的事情,順便總結(jié)一下Cookie的各個知識點
Cookie,是站點為了訪客的一些信息來區(qū)分用戶(Identifier)或者傳遞信息,特別是在big data的現(xiàn)在,更有利于站點site對用戶行為和地區(qū)傾向進行大數(shù)據(jù)分析,也可以為推薦系統(tǒng)做前期的基礎(chǔ)數(shù)據(jù)訓(xùn)練集。
Cookie存在哪里?
一般存在瀏覽器目錄中的文本文件中
Cookie分為多少種?
- 帶失效時間
expires的,在下次訪問之前,如果失效時間到期,會自動清除對應(yīng)cookie,expires和maxage的概念差不多,通常兩個時間都是一樣的,一個是時間,一個時間長度,前者是HTTP/1.0 protocol,后者是HTTP/1.1 protocol,為了向下兼容而已,所以,最好是兩個參數(shù)都設(shè)置 - 跟隨
session結(jié)束就自動清除的,這種cookie很常見,通常你會在console看到它的expires時間是1969年的或者所邊當(dāng)前時間還要早的時間,這種cookies會在會話結(jié)束的同時清除掉
Cookie的工作原理是什么?
前面我們說了Cookie一般存在瀏覽器目錄中的文本文件中,并且會根據(jù)domain分開存放,比如,當(dāng)你輸入jianshu.com的時候,瀏覽器會向jianshu發(fā)送一個request,然后server根據(jù)request來返回response,把結(jié)果在顯示器中顯示,當(dāng)你發(fā)送這個request的時候,瀏覽器會尋找當(dāng)前瀏覽器目錄中是否存在jianshu.com的相關(guān)cookie,如果有,瀏覽器會把Cookie文件中的數(shù)據(jù)放在request header中一起向server發(fā)送,服務(wù)器收到Cookie數(shù)據(jù),服務(wù)器會根據(jù)你的cookie信息做一些相應(yīng)的處理,比如第一次訪問的話,會為你創(chuàng)建一個新的session id,否者來檢測你是否需重新登錄等等操作。
Cookie包含哪些字段?
主要包括server、expires、name、value、secure、httpOnly、path,其中服務(wù)器只想知道name和value字段,其余的字段有的為了存儲,有的為了安全性
如何查看Cookie?
比如在chrome下打開jianshu.com,F(xiàn)12 -> Application -> Cookies -> http://www.itdecent.cn

也可以在Console里邊輸入document.cookies,但是只顯示非HTTP的cookie name和value,沒有其他信息
如何操作cookie?
分為兩種:第一種在前端對cookie進行操作,以chrome為例子,可以直接在console里邊對cookie進行修改,例如我們將default_font改成Simplified(當(dāng)然這只是舉個例子,至于修改完重新發(fā)送請求到j(luò)ianshu server之后會不會有作用,這個取決于jianshu server),F(xiàn)12 -> Console,輸入:
document.cookie = "default_font=Simplified;path=/"
注意:name、domain、path一定要對應(yīng)正確,這里的cookie domain為www.itdecent.cn,所以不需要顯式設(shè)置,結(jié)果如下:

同樣的也可以刪除cookie,只需要將expires設(shè)置成比現(xiàn)在早的時間就可以了,順便分享一個前端修改指定cookie過期時間為一年的腳本,下面是修改_ga的過期時間,可自行根據(jù)需求修改:
for(i in cookie_list){
target = cookie_list[i];
if(target.includes('_ga')){
var date = new Date();
var c_time = date.getTime();
var age = 60*1000*60*24*365; // one year expiration
date.setTime(c_time + age);
document.cookie = target+";expires="+date.toGMTString()+";path=/";
}
}
第二種是后端服務(wù)器操作,可以直接在response上面進行操作,你可以直接抹掉某個cookie
response.clearCookie('default_font')
這個時候回來的response header就不會帶default_font這個cookie了
也可以修改已存在的cookie過期時間或者加入新的cookie,nodejs的application可以使用cookie.js
res.setHeader('Set-Cookie', cookie.serialize('my_cookie', 'my_value', {
httpOnly: false,
expires: "Mon, 11 Jun 2018 05:47:25 GMT"
maxAge: 60 * 60 * 24 * 7 // 1 week
}));
這個時候瀏覽器就會接受到一個包含cookie為my_cookie=my_value,并且過期時間為一個星期的response。
為什么我設(shè)置了cookie沒有生效?
首先可能有兩個問題
注意一下domain和path,必須完全對應(yīng)可以設(shè)置,比如你要修改某一個cookie,修改的時候必須指定與其一樣的domain和path才可以生效,否者不生效,另外,當(dāng)前域不可以寫其他域的cookie,子域名除外。
Cookie的安全性
既然cookie這么容易修改,畢竟cookie輸入個人信息,容易獲取,就容易被利用,那么我們自然而然會想到安全性問題,這里我能想到的有四種方式,在后端服務(wù)器對cookie進行適當(dāng)?shù)奶幚?,可以提高cookie的安全性:
- 在設(shè)置cookie的時候,加上以下參數(shù),指明該cookie只用來HTTP請求使用,這個時候前端或者瀏覽器是拿不到這個cookie的,也就是使用document.cookie是不會出現(xiàn)的,默認為false:
res.setHeader('Set-Cookie', cookie.serialize('my_cookie', 'my_value', {
httpOnly: true,
expires: "Mon, 11 Jun 2018 05:47:25 GMT"
maxAge: 60 * 60 * 24 * 7 // 1 week
}));
- 后端設(shè)置以下參數(shù),使得cookie只在https protocol下傳輸,如果把https改成http,cookie無法跟隨請求一起發(fā)送到server端,在發(fā)送cookie之前就已啟用了加密傳輸協(xié)議https:
res.setHeader('Set-Cookie', cookie.serialize('my_cookie', 'my_value', {
httpOnly: true,
secure: true,
expires: "Mon, 11 Jun 2018 05:47:25 GMT"
maxAge: 60 * 60 * 24 * 7 // 1 week
}));
- 設(shè)置expires的時間不要太長,如果必要,將其設(shè)置成跟隨session的結(jié)束而結(jié)束,默認可以不指定expires時間,或者設(shè)置一個比當(dāng)前時間要早的時間:
res.setHeader('Set-Cookie', cookie.serialize('my_cookie', 'my_value', {
httpOnly: true,
secure: true,
expires: "Thu, 1 Jan 1970 00:00:00 GMT"
}));
- 對敏感的cookie信息進行加密處理,防止被有意利用,例如MD5加密
在此,給各位需要做GDPR的同學(xué)們一個建議,對cookie的控制,最好在server器端處理,避免在前端處理,因為他實際上是一個在線修改而已,那些你希望存在的cookie,實際上已經(jīng)寫入了訪客瀏覽器目錄中,只是在后續(xù)js處理中被你修改了而已,這是一種很搞笑的行為。
** 文章所有步驟都是經(jīng)過實踐檢驗并可行,若有問題,下方請評論。
——END——
作者 : Eason,專注各種技術(shù)、平臺、集成,不滿現(xiàn)狀,喜歡改改改
文章、技術(shù)合作
Email : eason.lau02@hotmail.com