天天看點

EF架構~二級域名中共享Session

回到目錄

對于一個有點規模的網站,都會有各個子網站,說是子網站,其實也都是獨立的站點,一般通過二次域名來分開,如www.zzl.com,它可以有很多子網站,如image.zzl.com,file.zzl.com,sale.zzl.com,manage.zzl.com,news.zzl.com等等!

而如果希望在各個項目中共享你的登陸狀态,我們通過的做法是通過cookies實作,但使用cookies就有安全性的問題,因為它的資訊儲存在用戶端,這是重所周知的,而session本身不支援跨域,即使是二級域名,也是不可以的.(cookies可以在各二級域名中共享資訊),當然,這隻是對于inpro的存儲方式來說的,如果你是sqlserver或者StateServer的方法,那麼,通過一些設定,還是可以實作session的跨域的,下面來說一下實作方式.

一 建立一個httpModule,在頁面加載完成後,執行這個方法,将域名的asp.net_sessionId重寫

/// <summary>
    /// session共享sessionId
    /// </summary>
    public class SessionProviderHttpModule : IHttpModule
    {
        private string m_RootDomain = string.Empty;

        public void Dispose()
        {

        }

        public void Init(HttpApplication context)
        {
            m_RootDomain = ".mvvm.com";

            Type stateServerSessionProvider = typeof(HttpSessionState).Assembly.GetType("System.Web.SessionState.OutOfProcSessionStateStore");
            FieldInfo uriField = stateServerSessionProvider.GetField("s_uribase", BindingFlags.Static | BindingFlags.NonPublic);

            if (uriField == null)
                throw new ArgumentException("UriField was not found");

            uriField.SetValue(null, m_RootDomain);

            context.EndRequest += new System.EventHandler(context_EndRequest);
        }

        void context_EndRequest(object sender, System.EventArgs e)
        {

            HttpApplication app = sender as HttpApplication;
            for (int i = 0; i < app.Context.Response.Cookies.Count; i++)
            {
                if (app.Context.Response.Cookies[i].Name == "ASP.NET_SessionId")
                {
                    app.Context.Response.Cookies[i].Domain = m_RootDomain;
                }
            }
        }
    }      

二 将這個httpModule注入到項目中

web.config方法

<sessionState cookieless="false"
                 timeout="50"
                 mode="StateServer"
                 stateConnectionString="tcpip=localhost:42424"/>
    <httpModules>
      <add name="CrossDomainCookieModule"
           type="EntityFrameworks.Application.Core.HttpModule.SessionProviderHttpModule,EntityFrameworks.Application.Core"/>
    </httpModules>      

預處理程式方法

/// <summary>
    /// 預處理代碼
    /// </summary>
    public class PreApplicationStartCode
    {
        public static void Start()
        {
            // Register our module
            Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(EntityFrameworks.Application.Core.HttpModule.SessionProviderHttpModule));
        }
    }      

三 設定系統資料庫相關項,啟動asp.net的session服務,如圖

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\aspnet_state\Parameters

AllowRemoteConnection值為1,Port值可以任意設定,預設為42424

四 當我們設定好上面内容後,我們的session共享就完成了,測試後的結果,如圖

EF架構~二級域名中共享Session
EF架構~二級域名中共享Session

通過圖上我們可以看到,它們的ASP.NET_SessionId是相同的,我們知道,浏覽器在沒有進行使用者session寫入時,每次重新整理,這個值都會變,但當使用者使用session序列化後,這個值就固定了,當你把浏覽器關閉後,這個值也同時消失,可以說,它是伺服器端session的唯一标示,這個值如果相同,伺服器就會認為,你的網站是在同一個域下的,它們的資訊是共享的,反之,它們就是自立獨立的,就像兩個應用程式域一樣,它們之間是不能互相通訊的.

 回到目錄

作者:倉儲大叔,張占嶺,

榮譽:微軟MVP

QQ:853066980

支付寶掃一掃,為大叔打賞!

EF架構~二級域名中共享Session