1. 程式人生 > >cookies與session的區別

cookies與session的區別

作用 enables 自動 購物 一段 通知 use 登錄 sessions

HTTP協議是無狀態的協議,所以服務端需要記錄用戶的狀態時,就需要用某種機制來識具體的用戶,這個機制就是Session。

當程序需要為某個客戶端的請求創建一個session的時候,服務器首先檢查這個客戶端的請求裏是否已包含了一個session標識 - 稱為 session id,如果已包含一個session id則說明以前已經為此客戶端創建過session,服務器就按照session id把這個 session檢索出來使用(如果檢索不到,可能會新建一個),如果客戶端請求不包含session id,則為此客戶端創建一個session並且生成一個與此session相關聯的session id,session id的值應該是一個既不會重復,又不容易被找到規律以仿造的字符串,這個 session id將被在本次響應中返回給客戶端保存。

在談論session機制的時候,常常聽到這樣一種誤解“只要關閉瀏覽器,session就消失了”。其實可以想象一下會員卡的例子,除非顧客主動對店家提出銷卡,否則店家絕對不會輕易刪除顧客的資料。對session來說也是一樣的,除非程序通知服務器刪除一個session,否則服務器會一直保留,程序一般都是在用戶做log off的時候發個指令去刪除session。然而瀏覽器從來不會主動在關閉之前通知服務器它將要關閉,因此服務器根本不會有機會知道瀏覽器已經關閉,之所以會有這種錯覺,是大部分session機制都使用會話cookie來保存session id,而關閉瀏覽器後這個 session id就消失了,再次連接服務器時也就無法找到原來的session。如果服務器設置的cookie被保存到硬盤上,或者使用某種手段改寫瀏覽器發出的HTTP請求頭,把原來的session id發送給服務器,則再次打開瀏覽器仍然能夠找到原來的session。

恰恰是由於關閉瀏覽器不會導致session被刪除,迫使服務器為seesion設置了一個失效時間,當距離客戶端上一次使用session的時間超過這個失效時間時,服務器就可以認為客戶端已經停止了活動,才會把session刪除以節省存儲空間。

大家都知道,http是無狀態的協議,客戶每次讀取web頁面時,服務器都打開新的會話,而且服務器也不會自動維護客戶的上下文信息,那麽要怎麽才能實現網上商店中的購物車呢,session就是一種保存上下文信息的機制,它是針對每一個用戶的,變量的值保存在服務器端,通過SessionID來區分不同的客戶,session是以cookie或URL重寫為基礎的,默認使用cookie來實現,系統會創造一個名為JSESSIONID的輸出cookie,我們叫做session cookie,以區別persistent cookies,也就是我們通常所說的cookie,註意session cookie是存儲於瀏覽器內存中的,並不是寫到硬盤上的,這也就是我們剛才看到的JSESSIONID,我們通常情是看不到JSESSIONID的,但是當我們把瀏覽器的cookie禁止後,web服務器會采用URL重寫的方式傳遞Sessionid,我們就可以在地址欄看到sessionid=KWJHUG6JJM65HS2K6之類的字符串。

具體來說cookie機制采用的是在客戶端保持狀態的方案。它是在用戶端的會話狀態的存貯機制,他需要用戶打開客戶端的cookie支持。cookie的作用就是為了解決HTTP協議無狀態的缺陷所作的努力.

而session機制采用的是一種在客戶端與服務器之間保持狀態的解決方案。同時我們也看到,由於采用服務器端保持狀態的方案在客戶端也需要保存一個標識,所以session機制可能需要借助於cookie機制來達到保存標識的目的。而session提供了方便管理全局變量的方式

session是針對每一個用戶的,變量的值保存在服務器上,用一個sessionID來區分是哪個用戶session變量,這個值是通過用戶的瀏覽器在訪問的時候返回給服務器,當客戶禁用cookie時,這個值也可能設置為由get來返回給服務器。

就安全性來說:當你訪問一個使用session 的站點,同時在自己機子上建立一個cookie,建議在服務器端的SESSION機制更安全些.因為它不會任意讀取客戶存儲的信息。

正統的cookie分發是通過擴展HTTP協議來實現的,服務器通過在HTTP的響應頭中加上一行特殊的指示以提示瀏覽器按照指示生成相應的cookie

從網絡服務器觀點看所有HTTP請求都獨立於先前請求。就是說每一個HTTP響應完全依賴於相應請求中包含的信息

狀態管理機制克服了HTTP的一些限制並允許網絡客戶端及服務器端維護請求間的關系。在這種關系維持的期間叫做會話(session)。

Cookies是服務器在本地機器上存儲的小段文本並隨每一個請求發送至同一個服務器。

明白了原理,我們就可以很容易的分辨出persistent cookies和session cookie的區別了,網上那些關於兩者安全性的討論也就一目了然了,session cookie針對某一次會話而言,會話結束session cookie也就隨著消失了,而persistent cookie只是存在於客戶端硬盤上的一段文本(通常是加密的),而且可能會遭到cookie欺騙以及針對cookie的跨站腳本攻擊,自然不如session cookie安全了。

通常session cookie是不能跨窗口使用的,當你新開了一個瀏覽器窗口進入相同頁面時,系統會賦予你一個新的sessionid,這樣我們信息共享的目的就達不到了,此時我們可以先把sessionid保存在persistent cookie中,然後在新窗口中讀出來,就可以得到上一個窗口SessionID了,這樣通過session cookie和persistent cookie的結合我們就實現了跨窗口的session tracking(會話跟蹤)。

在一些web開發的書中,往往只是簡單的把Session和cookie作為兩種並列的http傳送信息的方式,session cookies位於服務器端,persistent cookie位於客戶端,可是session又是以cookie為基礎的,明白的兩者之間的聯系和區別,我們就不難選擇合適的技術來開發web service了

cookies和session的關系1。 Cookie是一種發送到客戶瀏覽器的文本串句柄,並保存在客戶機硬盤上,

可以用來在某個Web站點會話之間持久地保持數據。Request和Response對象都有

一組Cookie。Request.cookie集合是一系列Cookie,從客戶端與HTTP Request一

起發送到Web服務器。反過來,如果你希望把Cookie發送到客戶機,就可以使用R

esponse.cookie
1、ExpiresAbsolute屬性
該屬性可以賦一個日期,過了這個日期Cookie就不能再被使用了。通過給Ex

pires屬性賦一個過期的日期,就可以刪除Cookie。如:
<%Response.cookies("passtime").expiresAbsolute="1/1/99"%>
2、Domain屬性
該屬性定義Cookie要傳送的唯一域。如:Cookie只傳送給Microsoft的人,

則可以使用以下代碼。
<%Response.Cookies("domain").Domain="www.microsoft.com"%>
3、ASP用來寫入Cookie即向客戶機發送Cookie的語法如下:
Response.Cookie("Cookie名").[("鍵名").屬性]=內容
如果某個ASP文件要創建一個Cookie,則下面的代碼可以放在ASP文件的第一

個<html>之前,以避免產生錯誤.
<%Response.Cookies("CookieName")="NewCookie" %>
<html>
......
</html>
4、同樣ASP用Request對象的Cookies集合來讀取Cookie,如:
<%Response.write Request.Cookies("CookieName")%>
下面以一個完整的例子來說明Cookie:
<%
dim Num
Num=Request.Cookies("Visit_num")
if Num>0 then
Num=Num+1
Response.write "您已是第" & Num & "次訪問本站點了。"
else
Response.write "歡迎您首次訪問本站。"
Num=1
end if
Response.Cookies("Visit_num")=Num
%>
在該例子中,首先讀取Cookies變量Visit_num,看用戶端計算機是否保存有

Cookies變量。如果有該變量,則說明用戶已經訪問過該頁面,同時輸入出訪問

次數。如果用戶是首次訪問該頁面,則其計算機內不會有Cookies變量,程序會

顯示“歡迎”字樣,然後將Cookies變量Visit_num存到用戶計算機中,以便該用

戶下一次訪問該頁面時給出“訪問的次數”信息。
5、Cookie字典
有時在一個頁面中可能需要定義很多個Cookies變量,為了更好地管理它,

在Cookies組件中常引入一人的概念“子鍵”。引用它的語法如下:
Request.Cookies("變更名")("子鍵名")
如下面的Cookie創建一個名為"Dictionary"的字典,其中保存了三個鍵值:
<%
Response.Cookie("info")("Myname")="jeff"
Response.Cookie("info")("Gender")="male"
Response.Cookie("info")("Myheight")="172"
%>
事實上客戶機上的Cookie字典是以字符串的形式存在:
info=Myname=jeff&Gender=male&Myheight=172
如果用戶沒有指定“子鍵”名而直接引用Cookies變量,將會返回一個包含

所有的“子鍵”名及值的字符串。例如上面這個例子包含三個“子鍵”:"Mynam

e"、"Gender"和"Myheight",當用戶沒有指定其“子鍵”而直接通過Request.Co

okies("info")來引用時,則會得到下列字符串:
info=Myname=jeff&Gender=male&Myheight=172
如果要把Cookie中讀取的所有數據,可以用下面的代碼得到:
<%For each cookie in Request.Cookies
if Not cookie.HasKeys then
Response.write cookie & "=" & Request.Cookies(cookie)
Else
for each key in Request.Cookies(cookie)
Response.write cookie&"("&key&")"&"="&

Request.Cookies(cookie)(key)
next
end if
next
%>


2。Session其實指的就是訪問者從到達某個特定主頁到離開為止的那段時間。每

一訪問者都會單獨獲得一個Session。在Web應用程序中,當一個用戶訪問該應用

時,Session類型的變量可以供這個用戶在該Web應用的所有頁面中共享數據;如

果另一個用戶也同時訪問該Web應用,他也擁有自己的Session變量,但兩個用戶

之間無法通過Session變量共享信息,而Application類型的變更則可以實現站點

多個用戶之間在所有頁面中共享信息。



1、SessionID屬性
該屬性返回當前會話的唯一標誌,為每一個Session分配不同的編號。
我曾在開發過程中就遇到對用戶的控制問題。它要實現的功能就是,針對某

個網站的一個模塊,當一個會員登錄後正在看此模塊時,另一個人用同樣的會員

名登錄,就不能瀏覽這個模塊。也就是說一個會員名同時只能一個人瀏覽此模塊

。我通過用會員名(假設為UserID,唯一)和SessionID來實現了控制。當會員

登錄時,給這個會員一個Session記錄登錄狀態如:Session("Status")="Logged

",同時把這個會員的Session.SessionID寫入數據庫。當他要瀏覽此模塊時,先

判斷其是否登錄,若已經登錄再判斷它的SessionID是否與數據庫記錄的相同,

如果不同則不能訪問。這樣,當另一個用戶用相同的會員名登錄時,那麽數據庫

中記錄的就是新的SessionID,前者訪問此模塊時就不能通過檢查。這就實現了

一個會員名同時只能一個人瀏覽某個模塊。這個功能在一些收費網站有很有特別

作用,它防止了一個會員名給多個人瀏覽的問題,為公司保障了利益。



2、TimeOut屬性
該屬性用來定義用戶Session對象的時限。如果用戶在規定的時間內沒有刷

新網頁,則Session對象就會終止。一般默認為20分鐘。



3、Abandon方法
該方法是Session對象的唯一方法,可以清除Session對象,用來消除用戶的

Session對象並釋放其所占的資源。如: <% Session.Abandon %>
4、Session_OnStart和Session_OnEnd事件
和Application一樣,當對象的例程每一次啟動時觸發Session_OnStart事件

,然後運行Session_Onstart事件的處理過程。也就是說,當服務器接收到應用

程序中的URL的HTTP請求時,觸發此事件,並建立一個Session對象。同理,這個

事件也必須定在Global.asa文件中。
當調用Session.Abandon方法時或者在TimeOut的時間內沒有刷新,這會觸發

Session_OnEnd事件,然後執行裏面的腳本。Session變量與特定的用戶相聯系,

針對某一個用戶賦值的Session變量是和其他用戶的Session變量完全獨立的,不

會存在相互影響。
Session應用一列:
與Application一樣,一個被定義為Session類型的數組只能將整個數組作為

一個對象,用戶不能直接改變Session數組中某個元素的值。為了創建一個Sessi

on數組,需先定義一個普通的數組,並對它的每一個元素賦初值,最後把它定義

為一個Session數組。如:
<%
dim array()
array=array("jeff","zhu","male")
Session("info")=array
Response.write Session("info")(0) &"-"
Response.write Session("info")(1) &"-"
Response.write Session("info")(2) &"<br>"
%>
<hr>
<%
array(0)="jun"
array(1)="li"
array(2)="female"
Session("info")=array
Response.write Session("info")(0) & "-"
Response.write Session("info")(1) & "-"
Response.write Session("info")(2) & "<br>"
%>
以上這段程序輸出結果是:
jeff-zhu-male
_____________
jun-li-female


Session是怎樣工作的?

Session其實是利用Cookie進行信息處理的,(參見後面有關Cookies的介紹),

當用戶首先進行了請求後,服務端就在用戶瀏覽器上創建了一個Cookie,當這個

Session結束時,其實就是意味著這個Cookie就過期了。
為這個用戶創建的Cookie的名稱是ASPSESSIONID。這個Cookie的唯一目的就是為

每一個用戶提供不同的身份認證。
註:如果你對名字是ASPSESSIONID的COOKIE感到好奇,你可以利用ServerVariab

les集合的COOKIE Header來接受這個信息,參看下面這個腳本:
<%=Request.ServerVariables(“HTTP COOKIE”) %>
你可以刷新不止一次而顯示結果依然不變。如果希望對ServerVariables集合有

Session變量自己不會存在用戶瀏覽器上。不過,ASPSESSIONID這個cookie需要

使用session變量。server使用ASPSESSIONID

cookie來將特定的用戶和特定的session信息聯系起來。沒有cookie的話,Serve

r就不會了解到每一個特定用戶在網站中移動的信息。
利用SessionID變量存儲ASPSESSIONID

cookie和直接對名為ASPSESSIONID的cookie賦值有很大不同。微軟利用了一個復

雜的數學算法對SessionID進行了加密措施,以防止黑客猜測出SessionID的值並

且依據這個獲得不該獲得的身份或權限。
註:你可以用兩種方法屏蔽掉SessionID,一種是將全站進行屏蔽,另外一種是

將一個單獨Active Server Page進行相應屏蔽。
如果想要將整個站點的Session操作進行屏蔽,你可以使用Internet Service

Manager。從Application設置對話框,點擊Active Server

Pages表並且取消對Enable Session State選項的選擇。
你還可以在特定的Active Server Page的首行加入使之屏蔽的語句來進行這種操

作。
<% EnableSessionState=False %>
由於Session對象使用了Cookies,那麽它的兼容性就受到了限制,一些老的瀏覽

器顯然是不行的,新的瀏覽器象是NetScape4.0也提供了屏蔽Cookie的選項。
這樣就出了問題、由於Cookie不能適用於所有瀏覽器,那麽在建站時你就必須註

意了,如果你的網站定位於大眾通用,就必須考慮各種不同的用戶情況。不過現

在確實有可以替代的方法,有些取代Cookies來進行身份認證的方法將在後面的

註:當前瀏覽器,是否發送一個Cookie在URL是區分大小寫的,因此,微軟提醒你

最好使用同樣的大小寫方式,例如一起使用/WWW/mypage.asp和/www/mypage.asp

肯定會使瀏覽器出錯。

cookies與session的區別