之前就有一篇COOKIE的類(lèi)似溫故文章了(http://blog.csdn.net/banmuhuangci/archive/2008/11/05/3229297.aspx),此文中重點(diǎn)敘述了COOKIE的Expires屬性的不可讀取問(wèn)題,以至于重新發(fā)回COOKIE時(shí)需要再次設(shè)置Expires屬性。
今天寫(xiě)這篇文章主要闡述一下SESSION的一些細(xì)節(jié)問(wèn)題以及SESSION和COOKIE的關(guān)系
首先,論壇上經(jīng)常會(huì)遇到的一個(gè)問(wèn)題是,SESSION安全嗎?答案是:安全,SESSION是保存在服務(wù)器上的,客戶(hù)端無(wú)法擅自修改值,因此是安全的,但是如果作為登錄狀態(tài)的判斷,SESSION是否安全就要看你是如何通過(guò)SESSION判斷登錄狀態(tài)了,這個(gè)問(wèn)題不是SESSION的問(wèn)題,而是開(kāi)發(fā)者的思路問(wèn)題。
另外就是,COOKIE在不設(shè)置Expires屬性時(shí) 關(guān)閉瀏覽器及過(guò)期,SESSION也是這樣嗎?答案:當(dāng)然不是。
SESSION的生存周期只與其過(guò)期時(shí)間有關(guān),也就是說(shuō),在ASP.NET 或ASP中如果不調(diào)用 Session.Clear()或Session.Abandon()方法,那么SESSION只會(huì)在預(yù)設(shè)的Session.TimeOut所設(shè)置的時(shí)間后消亡。因此,SESSION消亡的條件就只有兩個(gè)A、過(guò)期,B、調(diào)用銷(xiāo)毀方法主動(dòng)銷(xiāo)毀。
可是很多人會(huì)問(wèn),既然如此為什么我關(guān)閉瀏覽器后立刻打開(kāi)頁(yè)面,依然沒(méi)有SESSION的回話(huà)狀態(tài)呢?
這種情況就要仔細(xì)的關(guān)心下SESSION和COOKIE的關(guān)系了。
在ASP.NET中,SESSION是需要COOKIE支持的,如果在用戶(hù)客戶(hù)端禁用了COOKIE或在配置文件中設(shè)置SESSION為無(wú)COOKIE的情況下,客戶(hù)端瀏覽器的地址欄會(huì)以明文方式顯示SESSION標(biāo)識(shí)出來(lái)以用來(lái)在服務(wù)器與客戶(hù)端之間傳遞保持狀態(tài)。因此,當(dāng)我們正常情況下使用SESSION的時(shí)候,實(shí)際上打開(kāi)瀏覽器訪(fǎng)問(wèn)網(wǎng)站,服務(wù)器分配一個(gè)會(huì)話(huà)給客戶(hù)端后也就同時(shí)創(chuàng)建了一個(gè)沒(méi)有設(shè)置Expires屬性的COOKIE用來(lái)保存該客戶(hù)端SESSION的標(biāo)識(shí),這樣客戶(hù)端請(qǐng)求服務(wù)器的時(shí)候,服務(wù)器會(huì)先獲取并檢查這個(gè)伴隨SESSION一起建立的COOKIE里的值,然后對(duì)比服務(wù)器上的SESSION.ID,知道是哪個(gè)客戶(hù)端的請(qǐng)求后再將屬于這個(gè)客戶(hù)端的SESSION用于程序處理。這就是在默認(rèn)情況下有COOKIE狀態(tài)的SESSION工作的基本流程,否則服務(wù)器怎么可能知道是哪個(gè)客戶(hù)端發(fā)送的請(qǐng)求,大家都知道HTTP是無(wú)狀態(tài)的。
結(jié)合之前關(guān)于COOKIE的文章和現(xiàn)在分析SESSION的工作流程,我們就知道,當(dāng)客戶(hù)端關(guān)閉瀏覽器之后,實(shí)際上消亡的不是SESSION而是伴隨SESSION創(chuàng)建的COOKIE,這個(gè)COOKIE消亡了之后,客戶(hù)端對(duì)服務(wù)器的請(qǐng)求中就不包含標(biāo)識(shí)該客戶(hù)端的信息,因此,服務(wù)器并不知道是哪個(gè)客戶(hù)端因?yàn)閷?duì)于服務(wù)器來(lái)說(shuō)他是新來(lái)的,所以就會(huì)重新創(chuàng)建并分配一個(gè)新的SESSION給他。因此在客戶(hù)端看來(lái)似乎SESSION就沒(méi)了,其實(shí)并不是,SESSION還在只是沒(méi)人來(lái)認(rèn)領(lǐng)了。
實(shí)際上,COOKIE和SESSION關(guān)系密切,MS不建議使用COOKIELESS的SESSION,因?yàn)镾ESSION被明文寫(xiě)在了URL里,這樣會(huì)很容易被篡改并被惡意利用。事實(shí)上,我們開(kāi)發(fā)中也絕少使用COOKIELESS的SESSION,所以正常情況下,SESSION是需要依賴(lài)COOKIE的,所以COOKIE在沒(méi)設(shè)置EXPRIES屬性時(shí)候的特征也會(huì)蒙蔽不少新開(kāi)發(fā)者。
需要注意的是,文中大部分提到的COOKIE是服務(wù)器創(chuàng)建SESSION時(shí)自動(dòng)創(chuàng)建的為SESSION服務(wù)的COOKIE,而不是開(kāi)發(fā)者手工創(chuàng)建的。
有經(jīng)驗(yàn)的開(kāi)發(fā)者通常會(huì)自定義另外的有一定有效期的COOKIE以補(bǔ)充解決SESSION無(wú)法長(zhǎng)期或在關(guān)閉瀏覽器后“丟失”的問(wèn)題。
最后以一個(gè)比喻來(lái)再次加深印象。
我們將整個(gè)過(guò)程想做投幣存儲(chǔ)服務(wù)
SESSION是一個(gè)儲(chǔ)藏柜,COOKIE是一個(gè)號(hào)牌,IIS或者說(shuō)服務(wù)器是我們的服務(wù)員。
當(dāng)你投幣(請(qǐng)求)的時(shí)候,服務(wù)員會(huì)給你開(kāi)一個(gè)儲(chǔ)藏柜,然后發(fā)給你一個(gè)號(hào)牌,你可以多次的拿號(hào)牌給服務(wù)員存取你對(duì)應(yīng)的儲(chǔ)藏柜里的東西,但當(dāng)有一天,你搞掉了你的號(hào)牌(關(guān)閉瀏覽器,COOKIE消失了),這時(shí)你將無(wú)法存取你之前的儲(chǔ)藏柜里的東西,只能重新投幣然后服務(wù)員重新發(fā)給你一個(gè)號(hào)牌并重新給你開(kāi)一個(gè)空的儲(chǔ)藏柜??墒悄阒暗膬?chǔ)藏柜仍然還在,里面也仍然還有你之前存儲(chǔ)的東西。存儲(chǔ)服務(wù)中心當(dāng)然也有他們自己的規(guī)定,就是如果20天內(nèi)沒(méi)有人存取的柜將會(huì)被清空,里面的東西都銷(xiāo)毀(會(huì)話(huà)過(guò)期)。當(dāng)然也有用戶(hù)會(huì)主動(dòng)的取消自己的儲(chǔ)藏柜(調(diào)用清楚或銷(xiāo)毀方法)。
我們也知道,存儲(chǔ)服務(wù)不會(huì)因?yàn)槟銇G失了號(hào)牌而主動(dòng)去清空對(duì)應(yīng)柜子的,因?yàn)樗⒉恢滥闶欠裾娴膩G失了號(hào)牌,而且他同樣不知道你丟失的是哪個(gè)號(hào)牌,因?yàn)樗麄兊奶?hào)牌是隨機(jī)生成而且號(hào)碼是條形碼或者磁卡,沒(méi)有可見(jiàn)的數(shù)字。
通過(guò)這個(gè)比喻,同時(shí)你就知道為什么不建議COOKIELESS的會(huì)話(huà)了,要知道,一個(gè)明文的號(hào)牌是多么的容易偽造,作為存儲(chǔ)服務(wù)中心的老板,你也不希望你的客戶(hù)的儲(chǔ)藏柜總是因?yàn)閯e人偽造號(hào)牌而丟失東西吧。
另外說(shuō)一下 Session.Clear()和Session.Abandon()的區(qū)別,CLEAR將SESSION中的所有項(xiàng)都清除,也就是說(shuō),所有想都沒(méi)了,SESSION中的所有項(xiàng)都是NULL,而ABANDON方法是直接將SESSION對(duì)象清除了。也有人說(shuō),ABANDON會(huì)觸發(fā)SESSION_END事件,是的,因?yàn)镋ND時(shí)間就是在SESSION被銷(xiāo)毀時(shí)發(fā)生的。
如對(duì)本文有疑問(wèn),請(qǐng)?zhí)峤坏浇涣髡搲?,廣大熱心網(wǎng)友會(huì)為你解答!! 點(diǎn)擊進(jìn)入論壇