cookie與session的關(guān)系
為什么會(huì)有cookie呢,大家都知道,http是無(wú)狀態(tài)的協(xié)議,客戶每次讀取web頁(yè)面時(shí),服務(wù)器都打開(kāi)新的會(huì)話,而且服務(wù)器也不會(huì)自動(dòng)維護(hù)客戶的上下文信息,那么要怎么才能實(shí)現(xiàn)網(wǎng)上商店中的購(gòu)物車(chē)呢,session就是一種保存上下文信息的機(jī)制,它是針對(duì)每一個(gè)用戶的,變量的值保存在服務(wù)器端,通過(guò) SessionID來(lái)區(qū)分不同的客戶,session是以cookie或URL重寫(xiě)為基礎(chǔ)的,默認(rèn)使用cookie來(lái)實(shí)現(xiàn),系統(tǒng)會(huì)創(chuàng)造一個(gè)名為 JSESSIONID的輸出cookie,我們叫做session cookie,以區(qū)別persistent cookies,也就是我們通常所說(shuō)的cookie,注意session cookie是存儲(chǔ)于瀏覽器內(nèi)存中的,并不是寫(xiě)到硬盤(pán)上的,這也就是我們剛才看到的JSESSIONID,我們通常情是看不到JSESSIONID的,但是當(dāng)我們把瀏覽器的cookie禁止后,web服務(wù)器會(huì)采用URL重寫(xiě)的方式傳遞Sessionid,我們就可以在地址欄看到 sessionid=KWJHUG6JJM65HS2K6之類的字符串。明白了原理,我們就可以很容易的分辨出persistent cookies和session cookie的區(qū)別了,網(wǎng)上那些關(guān)于兩者安全性的討論也就一目了然了,session cookie針對(duì)某一次會(huì)話而言,會(huì)話結(jié)束session cookie也就隨著消失了,而persistent cookie只是存在于客戶端硬盤(pán)上的一段文本(通常是加密的),而且可能會(huì)遭到cookie欺騙以及針對(duì)cookie的跨站腳本攻擊,自然不如 session cookie安全了。
通常session cookie是不能跨窗口使用的,當(dāng)你新開(kāi)了一個(gè)瀏覽器窗口進(jìn)入相同頁(yè)面時(shí),系統(tǒng)會(huì)賦予你一個(gè)新的sessionid,這樣我們信息共享的目的就達(dá)不到了,此時(shí)我們可以先把sessionid保存在persistent cookie中,然后在新窗口中讀出來(lái),就可以得到上一個(gè)窗口SessionID了,這樣通過(guò)session cookie和persistent cookie的結(jié)合我們就實(shí)現(xiàn)了跨窗口的session tracking(會(huì)話跟蹤)。
在一些web開(kāi)發(fā)的書(shū)中,往往只是簡(jiǎn)單的把Session和cookie作為兩種并列的http傳送信息的方式,session cookies位于服務(wù)器端,persistent cookie位于客戶端,可是session又是以cookie為基礎(chǔ)的,明白的兩者之間的聯(lián)系和
區(qū)別,我們就不難選擇合適的技術(shù)來(lái)開(kāi)發(fā)web service了
cookie
Session是由應(yīng)用服務(wù)器維持的一個(gè)服務(wù)器端的存儲(chǔ)空間,用戶在連接服務(wù)器時(shí),會(huì)由服務(wù)器生成一個(gè)唯一的SessionID,用該SessionID 為標(biāo)識(shí)符來(lái)存取服務(wù)器端的Session存儲(chǔ)空間。而SessionID這一數(shù)據(jù)則是保存到客戶端,用Cookie保存的,用戶提交頁(yè)面時(shí),會(huì)將這一 SessionID提交到服務(wù)器端,來(lái)存取Session數(shù)據(jù)。這一過(guò)程,是不用開(kāi)發(fā)人員干預(yù)的。所以一旦客戶端禁用Cookie,那么Session也會(huì)失效。
服務(wù)器也可以通過(guò)URL重寫(xiě)的方式來(lái)傳遞SessionID的值,因此不是完全依賴Cookie。如果客戶端Cookie禁用,則服務(wù)器可以自動(dòng)通過(guò)重寫(xiě)URL的方式來(lái)保存Session的值,并且這個(gè)過(guò)程對(duì)程序員透明。
可以試一下,即使不寫(xiě)Cookie,在使用request.getCookies();取出的Cookie數(shù)組的長(zhǎng)度也是1,而這個(gè)Cookie的名字就是JSESSIONID,還有一個(gè)很長(zhǎng)的二進(jìn)制的字符串,是SessionID的值。
Cookie是客戶端的存儲(chǔ)空間,由瀏覽器來(lái)維持。
總結(jié):
1:cookie是通過(guò)頭部header返回到瀏覽器中并保存在磁盤(pán)中,下次再次訪問(wèn)該服務(wù)器中。瀏覽器會(huì)自動(dòng)把該cookie傳輸?shù)椒?wù)器中。
2:Session與Cookie是一對(duì)的,Session使用的基礎(chǔ)就是cookie。
3:cookie分為兩種,如果設(shè)置cookie時(shí)沒(méi)有設(shè)置有效時(shí)間,就表示該cookie是臨時(shí)性的,只保存在瀏覽器的內(nèi)存中,即seesion-cookie,只要關(guān)閉瀏覽器,該cookie即將消失。
如果cookie設(shè)置了有效時(shí)間,就表示該cookie是持久化的,即persistent cookie。此外還可以為持久化cookie設(shè)置域名和路徑。
4:當(dāng)禁止cookie后,就返回通過(guò)url地址返回cookie Id。
5:如來(lái)是否自定義cookie值,服務(wù)器都會(huì)自動(dòng)產(chǎn)生一個(gè)cookie值,名稱為: JSESSIONID,而值就是服務(wù)器中的sessionid值。
創(chuàng)建cookie的步驟: 以java為例:
1: 創(chuàng)建cookie對(duì)象:
Cookie cookie =
new
Cookie(
"cookiename"
,
"cookievalue"
);
2:設(shè)置有效期:
cookie.setMaxAge(
3600
);
3:設(shè)置路徑:
cookie.setPath(
"/"
);
//設(shè)置路徑,這個(gè)路徑即該工程下都可以訪問(wèn)該cookie 如果不設(shè)置路徑,那么只有設(shè)置該cookie路徑及其子路徑可以訪問(wèn) 4:設(shè)置域名:cookie.setDomain(".zl.org") ; //域名要以“.”開(kāi)頭
5:在返回對(duì)象中添加cookie對(duì)象:response.addCookie(cookie) ;
6:返回對(duì)象response其他的操作。
以下為Java操作Cookie實(shí)例:
java對(duì)cookie的操作比較簡(jiǎn)單,主要介紹下建立cookie和讀取cookie,以及如何設(shè)定cookie的生命周期和cookie的路徑問(wèn)題。
建立一個(gè)無(wú)生命周期的cookie,即隨著瀏覽器的關(guān)閉即消失的cookie,代碼如下
HttpServletRequest request
HttpServletResponse response
Cookie cookie = new Cookie("cookiename","cookievalue");
response.addCookie(cookie);
下面建立一個(gè)有生命周期的cookie,可以設(shè)置他的生命周期
cookie = new Cookie("cookiename","cookievalue");
cookie.setMaxAge(3600);
//設(shè)置路徑,這個(gè)路徑即該工程下都可以訪問(wèn)該cookie 如果不設(shè)置路徑,那么只有設(shè)置該cookie路徑及其子路徑可以訪問(wèn)
cookie.setPath("/");
response.addCookie(cookie);
下面介紹如何讀取cookie,讀取cookie代碼如下
Cookie[] cookies = request.getCookies();//這樣便可以獲取一個(gè)cookie數(shù)組
for(Cookie cookie : cookies){
cookie.getName();// get the cookie name
cookie.getValue(); // get the cookie value
}
上面就是基本的讀寫(xiě)cookie的操作。我們?cè)趯?shí)際中最好進(jìn)行一下封裝,比如增加一個(gè)cookie,我們關(guān)注的是cookie的name,value,生命周期,所以進(jìn)行封裝一個(gè)函數(shù),當(dāng)然還要傳入一個(gè)response對(duì)象,addCookie()代碼如下
/**
* 設(shè)置cookie
* @param response
* @param name cookie名字
* @param value cookie值
* @param maxAge cookie生命周期 以秒為單位
*/
public static void addCookie(HttpServletResponse response,String name,String value,int maxAge){
Cookie cookie = new Cookie(name,value);
cookie.setPath("/");
if(maxAge>0) cookie.setMaxAge(maxAge);
response.addCookie(cookie);
}
讀取cookie的時(shí)候,為了方便我們的操作,我們希望封裝一個(gè)函數(shù),只要我們提供cookie的name,我們便可以獲取cookie的value,帶著這個(gè)想法,很容易想到將cookie封裝到Map里面,于是進(jìn)行下面的封裝.
/**
* 根據(jù)名字獲取cookie
* @param request
* @param name cookie名字
* @return
*/
public static Cookie getCookieByName(HttpServletRequest request,String name){
Map<String,Cookie> cookieMap = ReadCookieMap(request);
if(cookieMap.containsKey(name)){
Cookie cookie = (Cookie)cookieMap.get(name);
return cookie;
}else{
return null;
}
}
/**
* 將cookie封裝到Map里面
* @param request
* @return
*/
private static Map<String,Cookie> ReadCookieMap(HttpServletRequest request){
Map<String,Cookie> cookieMap = new HashMap<String,Cookie>();
Cookie[] cookies = request.getCookies();
if(null!=cookies){
for(Cookie cookie : cookies){
cookieMap.put(cookie.getName(), cookie);
}
}
return cookieMap;
}
建立一個(gè)無(wú)生命周期的cookie,即隨著瀏覽器的關(guān)閉即消失的cookie,代碼如下
HttpServletRequest request
HttpServletResponse response
Cookie cookie = new Cookie("cookiename","cookievalue");
response.addCookie(cookie);
下面建立一個(gè)有生命周期的cookie,可以設(shè)置他的生命周期
cookie = new Cookie("cookiename","cookievalue");
cookie.setMaxAge(3600);
//設(shè)置路徑,這個(gè)路徑即該工程下都可以訪問(wèn)該cookie 如果不設(shè)置路徑,那么只有設(shè)置該cookie路徑及其子路徑可以訪問(wèn)
cookie.setPath("/");
response.addCookie(cookie);
下面介紹如何讀取cookie,讀取cookie代碼如下
Cookie[] cookies = request.getCookies();//這樣便可以獲取一個(gè)cookie數(shù)組
for(Cookie cookie : cookies){
cookie.getName();// get the cookie name
cookie.getValue(); // get the cookie value
}
上面就是基本的讀寫(xiě)cookie的操作。我們?cè)趯?shí)際中最好進(jìn)行一下封裝,比如增加一個(gè)cookie,我們關(guān)注的是cookie的name,value,生命周期,所以進(jìn)行封裝一個(gè)函數(shù),當(dāng)然還要傳入一個(gè)response對(duì)象,addCookie()代碼如下
/**
* 設(shè)置cookie
* @param response
* @param name cookie名字
* @param value cookie值
* @param maxAge cookie生命周期 以秒為單位
*/
public static void addCookie(HttpServletResponse response,String name,String value,int maxAge){
Cookie cookie = new Cookie(name,value);
cookie.setPath("/");
if(maxAge>0) cookie.setMaxAge(maxAge);
response.addCookie(cookie);
}
讀取cookie的時(shí)候,為了方便我們的操作,我們希望封裝一個(gè)函數(shù),只要我們提供cookie的name,我們便可以獲取cookie的value,帶著這個(gè)想法,很容易想到將cookie封裝到Map里面,于是進(jìn)行下面的封裝.
/**
* 根據(jù)名字獲取cookie
* @param request
* @param name cookie名字
* @return
*/
public static Cookie getCookieByName(HttpServletRequest request,String name){
Map<String,Cookie> cookieMap = ReadCookieMap(request);
if(cookieMap.containsKey(name)){
Cookie cookie = (Cookie)cookieMap.get(name);
return cookie;
}else{
return null;
}
}
/**
* 將cookie封裝到Map里面
* @param request
* @return
*/
private static Map<String,Cookie> ReadCookieMap(HttpServletRequest request){
Map<String,Cookie> cookieMap = new HashMap<String,Cookie>();
Cookie[] cookies = request.getCookies();
if(null!=cookies){
for(Cookie cookie : cookies){
cookieMap.put(cookie.getName(), cookie);
}
}
return cookieMap;
}
posted on 2013-11-26 00:01 奮斗成就男人 閱讀(177) 評(píng)論(0) 編輯 收藏