cookie的介紹和使用
一、什麼是cookie
是由服務器端生成,發送給客戶端(一般指瀏覽器),瀏覽器將cookie以鍵值對的形式保存到某個目錄下的文本文件內。下次請求該網站時就把cookie發送回服務器。(cookie就是一個小文件,瀏覽器對其大小一般限制在4k,用來記錄一些信息(一般用作標識))
二、cookie的作用
web應用程序是使用Http協議傳輸數據的,而Http協議是無狀態的,一旦數據交換完成就會斷開連接,再次交換就要重新建立連接,此時,服務器並不知道該瀏覽器與自己進行過數據交互。瀏覽器在發送請求後,服務器除了正常的響應之外,會在響應頭裡加入一個set-cookie:id=XXX,瀏覽器接收之後會存入本地文檔(txt),下次向該服務器發送請求時,會附帶此cookie.
三、cookie的生命周期
Cookie可以保持登錄信息到用戶下次與服務器的會話,換句話說,下次訪問同一網站時,用戶會發現不必輸入用戶名和密碼就已經登錄了(不排除用戶手工刪除Cookie)。而還有一些Cookie在用戶退出會話的時候就被刪除了,這樣可以有效保護個人隱私。Cookie在生成時就會被指定一個Expire值,這就是Cookie的生存周期,在這個周期內Cookie有效,超出周期Cookie就會被清除。有些頁面將Cookie的生存周期設置為「0」或負值,這樣在關閉瀏覽器時,就馬上清除Cookie,不會記錄用戶信息,更加安全。
四、cookie的特點
1.需要遵循瀏覽器的同源策略(兩個網站即使根域名相同,端口或者子域名不同,那這兩個網站就分別擁有自己的cookie,並且不能互相操作)
2.內存大小有限制(每個瀏覽器對其個數的限制不相同,每個域名在20~50之間,大小一般都限制在4K)
3.cookie的安全性較低,存儲的數據容易被竊取
五、cookie的安全性問題及其解決方案
1.cookie欺騙
攻擊者在拿到cookie後可以通過模擬身份驗證,將該cookie向服務器提交,冒充該cookie的擁有者訪問網站竊取用戶信息。
2.cookie截獲
cookie以純文本的形式在瀏覽器和服務器之間傳遞,在web通信時極容易被非法用戶截獲和利用。非法用戶截獲cookie後,在cookie的有效時間內重新發放給服務器,那麼這個非法用戶就擁有了這個合法用戶的所有權限。
3.Flash的內部代碼
Flash中有一個getURL()函數,Flash利用它自動打開指定的頁面。那麼這個就意味着,你在觀看Flash動畫時,在Flash的內部可以悄無聲息的打開一個極小的不易發現的包含特殊操作的頁面,可以是木馬,可以向遠端輸入當前cookie或者用戶信息,這是非常危險的,由於這個是Flash內部的操作,所以網站無法禁止,要想避免,盡量打開本地防火牆以及訪問正規網站。
4.解決方案
(1)設置cookie有效期不要太長
(2)設置HttpOnly屬性為true,可以防止js腳本讀取cookie信息,有效的防止XSS攻擊
(3)設置複雜的cookie,進行加密(例如:cookie的key使用uuid,隨機生成,cookie的value使用複雜組合,用戶名+當前時間+有效時間+隨機數)
(4)驗證token,每次請求,都去將當前cookie和ip組合起來加密後的token與保存的token作對比,只有完全對應才能驗證成功。
(5)sessionId雖然放在cookie中,但是相對的session更安全,可以將相對重要的信息存入session。
註:瀏覽器第一次請求服務器時,服務器會生成一個session,並返回給瀏覽器,這個sessionId會被保存在瀏覽器的會話cookie中。session在服務器的默認有效時間是30分鐘。
(6)使用https,如果網站支持https,那麼可以為cookie設置Secure屬性為true,它的意思是,cookie只能使用https協議發送給服務器,而https比http更加安全。
六、cookie的使用
JS版本
function addCookie(key, value, day, path, domain) { // 1.處理默認保存的路徑 var index = window.location.pathname.lastIndexOf("/") var currentPath = window.location.pathname.slice(0, index); path = path || currentPath; // 2.處理默認保存的domain domain = domain || document.domain; // 3.處理默認的過期時間 if(!day){ document.cookie = key+"="+value+";path="+path+";domain="+domain+";"; }else{ var date = new Date(); date.setDate(date.getDate() + day); document.cookie = key+"="+value+";expires="+date.toGMTString()+";path="+path+";domain="+domain+";"; } } function getCookie(key) { // console.log(document.cookie); var res = document.cookie.split(";"); // console.log(res); for(var i = 0; i < res.length; i++){ // console.log(res[i]); var temp = res[i].split("="); // console.log(temp); if(temp[0].trim() === key){ return temp[1]; } } } // 默認情況下只能刪除默認路徑中保存的cookie, 如果想刪除指定路徑保存的cookie, 那麼必須在刪除的時候指定路徑才可以 function delCookie(key, path) { addCookie(key, getCookie(key), -1, path); }
JQ版本
(function ($, window) {
$.extend({
addCookie: function (key, value, day, path, domain) {
// 1.處理默認保存的路徑
var index = window.location.pathname.lastIndexOf("/")
var currentPath = window.location.pathname.slice(0, index);
path = path || currentPath;
// 2.處理默認保存的domain
domain = domain || document.domain;
// 3.處理默認的過期時間
if(!day){
document.cookie = key+"="+value+";path="+path+";domain="+domain+";";
}else{
var date = new Date();
date.setDate(date.getDate() + day);
document.cookie = key+"="+value+";expires="+date.toGMTString()+";path="+path+";domain="+domain+";";
}
},
getCookie:function (key) {
// console.log(document.cookie);
var res = document.cookie.split(";");
// console.log(res);
for(var i = 0; i < res.length; i++){
// console.log(res[i]);
var temp = res[i].split("=");
// console.log(temp);
if(temp[0].trim() === key){
return temp[1];
}
}
},
delCookie:function (key, path) {
addCookie(key, getCookie(key), -1, path);
}
});
})(