ASP.NET中在不同的子域中共享Session的具體方法
今天遇到了這個(gè)問(wèn)題,于是研究了一下。要解決這個(gè)問(wèn)題,首先就要明白一些Session的機(jī)理。Session在服務(wù)器是以散列表形式存在的,我們都知道Session是會(huì)話級(jí)的,每個(gè)用戶訪問(wèn)都會(huì)生成一個(gè)Session。那么服務(wù)器是怎么區(qū)分不同用戶的Session?又是怎么將不同用戶的Session與不同的用戶綁定的呢?下面我們來(lái)研究一下,以下純屬我個(gè)人的理解,如有錯(cuò)誤請(qǐng)指證。
Session在服務(wù)器端是以散列表的形式存在的,區(qū)分每一個(gè)Session是通過(guò)SessionID來(lái)實(shí)現(xiàn)的,所以可以說(shuō)這個(gè)SessionID是一個(gè)Key是一個(gè)全局唯一的值。我們可以通過(guò)ASP.NET來(lái)打印出SessionID,如下代碼:
protected void Page_Load(object sender, EventArgs e)
{
Response.Write(Session.SessionID.ToString());
}
這樣我們就得到了這樣的值:0julmoedn0kz3gyfnr1vksv0,有點(diǎn)像是GUID,就算不是算法也都是類(lèi)似的,主要就是為了保證全局唯一性。這樣就達(dá)到了區(qū)分不同用戶的Session的目的。接下來(lái)還有第二個(gè)問(wèn)題,那就是SessionID有了,但是它又是怎么和相應(yīng)的訪問(wèn)者(用戶)綁定的呢?比如說(shuō)用戶A訪問(wèn)維護(hù)了自己的SessionID,用戶B訪問(wèn)也維護(hù)了自己的SessionID。我們都知道web是基于http無(wú)鏈接的,他們又是怎么做到的呢?沒(méi)錯(cuò),答案就是在客戶端存儲(chǔ)了自己的SessionID。瀏覽器存儲(chǔ)SessionID有兩種方式,一種就是利用Cookies;還有一種就是利用url參數(shù)(這種我們不常用,很不友好)。
話題說(shuō)到Cookies上來(lái)了,怎么的?沒(méi)想到Session和Cookies還有這樣的關(guān)系吧?(很多人知道,別BS我)沒(méi)錯(cuò),當(dāng)我們請(qǐng)求一個(gè)URL時(shí)候,服務(wù)器會(huì)生成一個(gè)全局的SessionID,并且把這個(gè)值以Cookies的形式保存在客戶端也就是瀏覽器(這里暫不討論url方式)。這樣當(dāng)用戶再去請(qǐng)求的時(shí)候,在http頭把這個(gè)SessionID的Cookie發(fā)到服務(wù)器端,服務(wù)器就去找這個(gè)SessionID,如果找到了。就證明這個(gè)用戶的狀態(tài)是存在的。
知道了這個(gè)原理,我們的問(wèn)題也就有眉頭了,即然是用Cookies來(lái)保存SessionID,那么我們就可以在Cooikes上做手腳了。我們都知道Cooikes記錄方式是以域(例如:http://www.dbjr.com.cn/)為區(qū)分的,這也是各種瀏覽器規(guī)定的。如果不這么做,安全性就會(huì)有問(wèn)題。我們要做的就是讓指定Cookies的父域方式,不指定具體指域,這樣Cookies就可以跨子域了。Cookies可以像這樣指定域:
protected void Page_Load(object sender, EventArgs e)
{
Response.Cookies["MyCook"].Domain = ".jb51.net";
}
這樣,我們所有的二級(jí)域全部是認(rèn)這一個(gè)主域的,比如a.jb51.net;b.jb51.net;user.jb51.net等等。有了這個(gè)認(rèn)識(shí),我想大家心里也有數(shù)了,該怎么怎么做,但是現(xiàn)在問(wèn)題是用來(lái)生成SessionID的方法是ASP.NET自動(dòng)實(shí)現(xiàn)的,我們又怎么去干涉它呢?這是這樣做的,不主動(dòng)干涉它,但是我可以操作它的Cookies啊。接下來(lái)我們就研究ASP.NET存SessionID的Cooike的名字是什么。經(jīng)過(guò)網(wǎng)上很容易就查找到了,名字是:ASP.NET_SessionId,這個(gè)就是SessionId的Cookies名字。我們可以在Session_Start中這樣寫(xiě):
protected void Session_Start(object sender, EventArgs e)
{
Response.Cookies["ASP.NET_SessionId"].Value = Session.SessionID.ToString();
Response.Cookies["ASP.NET_SessionId"].Domain = ".jb51.net";
}
代碼的意思是每次會(huì)話開(kāi)始的時(shí)候,我都把ASP.NET_SessionId這個(gè)Cookie重寫(xiě)成我們已有的SessionID,并且把這個(gè)Cookie的domain指定為父域,比如:.jb51.net,這樣就可以實(shí)現(xiàn)跨子域的Session共享了。怎么樣很簡(jiǎn)單吧?
我們還有一個(gè)外題問(wèn)題,就是客戶端保存的問(wèn)題解決了,但是服務(wù)器端的Session怎么辦?一般情況下我們不同的子域做的是指向不同的服務(wù)器的,比如user.jb51.net 專(zhuān)門(mén)一臺(tái)服務(wù)器,yellow.jb51.net專(zhuān)門(mén)一臺(tái)服務(wù)器。這時(shí)它們別說(shuō)是進(jìn)程了,連物理上都不是一個(gè)了。Session怎么共享?這時(shí)就用到另一個(gè)方法了,我們默認(rèn)的Session是存儲(chǔ)在asp.net進(jìn)程中的,這樣沒(méi)法互相訪問(wèn),如下面所示:
<sessionState mode="InProc" />
我們可以修改為State Server方式,這是一個(gè)單獨(dú)的服務(wù)可以用來(lái)存儲(chǔ)ASP.NET Session的,它支持分布式遠(yuǎn)程主機(jī)的,這樣我們可以用一臺(tái)服務(wù)器來(lái)提供Session服務(wù),如下所示:
<sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" timeout="30" />
這樣,就完全實(shí)現(xiàn)了不同子域的Session共享了。
前面說(shuō)到Url保存SessionId的方式,由于不常用,給大家演示一下,如下配置就可以了:
<sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" timeout="30" cookieless="true" />
cookieless屬性指定是否用cookie來(lái)保存SessionId,我們運(yùn)行一下得到下面的樣子:
http://localhost:3380/(S(dqxcs455n4u2vg55ia51fvqg))/default.aspx
相關(guān)文章
ASP.NET Core使用EF保存數(shù)據(jù)、級(jí)聯(lián)刪除和事務(wù)使用
這篇文章介紹了ASP.NET Core使用EF保存數(shù)據(jù)、級(jí)聯(lián)刪除和事務(wù)使用的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04asp.net實(shí)現(xiàn)XML文件讀取數(shù)據(jù)綁定到DropDownList的方法
這篇文章主要介紹了asp.net實(shí)現(xiàn)XML文件讀取數(shù)據(jù)綁定到DropDownList的方法,結(jié)合實(shí)例形式分析了asp.net針對(duì)xml文件操作及DropDownList控件的使用技巧,需要的朋友可以參考下2017-02-02ASP.NET頁(yè)面之間傳值的方式之Application實(shí)例詳解
這篇文章主要介紹了ASP.NET頁(yè)面之間傳值的方式之Application實(shí)例詳解,需要的朋友可以參考下2017-10-10HttpRequest的QueryString屬性 的一點(diǎn)認(rèn)識(shí)
我們開(kāi)發(fā)asp.net程序獲取QueryString時(shí),經(jīng)常性的遇到一些url編碼問(wèn)題2012-11-11.NET性能調(diào)優(yōu)之一:ANTS Performance Profiler的使用介紹
本系列文章主要會(huì)介紹一些.NET性能調(diào)優(yōu)的工具、Web性能優(yōu)化的規(guī)則(如YSlow)及方法等等內(nèi)容。成文前最不希望看到的就是園子里不間斷的“哪個(gè)語(yǔ)言好,哪個(gè)語(yǔ)言性能高”的爭(zhēng)論,不多說(shuō),真正的明白人都應(yīng)該知道這樣的爭(zhēng)論有沒(méi)有意義,希望我們能從實(shí)際性能優(yōu)化的角度去討論問(wèn)題2013-01-01Asp.net?core?使用SignalR推送消息過(guò)程詳解
ASP.NET?Core?SignalR?是一個(gè)開(kāi)放源代碼庫(kù),可用于簡(jiǎn)化向應(yīng)用添加實(shí)時(shí)?Web?功能。?實(shí)時(shí)?Web?功能使服務(wù)器端代碼能夠?qū)?nèi)容推送到客戶端,本文重點(diǎn)給大家介紹Asp.net?core?使用SignalR推送消息,感興趣的朋友一起看看吧2022-03-03.NET?Core支持Cookie和JWT混合認(rèn)證、授權(quán)的方法
這篇文章主要介紹了.NET?Core如何支持Cookie和JWT混合認(rèn)證、授權(quán),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-01-01