標籤:
在做一些應用網站時,我們可能會碰到這樣一種情況:整個項目是由多個網站組成的,而我們要實現使用者從一個網站登入後,跳轉到其他網站不需要重複登入,即實現單點登入。目前實現單點登入的技術也有好幾種,這篇文章描述一下如何使用ASP.NET2.0和SQL Server來實現單點登入。一般在使用者登入成功後,我們需要把使用者登入成功的資訊儲存在Session裡,但是Session的值只能儲存在使用者當前訪問的網站下,只要我們實現了Session的跨站共用,也就基本上實現了使用者在一個網站登入成功後在其他網站不需要重複登入,在這裡,我們使用SQL Server來儲存Session狀態,實現多個網站共用Session。
開發環境:WindowsXP、VS2005、.NET Framework 2.0、SQL Server 2000
首先我們需要建立一個單獨的資料庫來儲存Session狀態,安裝了Framework2.0後,我們可以在“C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727”目錄下找到一個“InstallPersistSqlState.sql”的SQL檔案,這個檔案就是用來建立儲存Session狀態的資料庫,只需要在查詢分析器中執行一下就可以了,當然也可以使用“UninstallPersistSqlState.sql”這個檔案來卸載已建立的狀態資料庫。
“InstallPersistSqlState.sql”執行完畢後,重新整理一下物件瀏覽器,我們就可以看到一個叫做“ASPState”的資料庫,資料庫中有兩個表,“ASPStateTempApplications”是用來儲存所有使用SQLServer儲存狀態的網站的,“ASPStateTempSessions”當然就是用來儲存所有Session的了。如:
建立完資料庫後,我們可以建立一個測試網站,來看一下Session狀態是否可以儲存到資料庫中,當然測試之前我們還需要對web.config檔案做一些設定。開啟web.config,在<system.web>標籤下建立<sessionState>標籤,mode屬性是說明把Session狀態儲存在什麼地方,具狀態服務器、記憶體、資料庫等,這裡我們要選擇SQLServer。設定如下所示:
[xhtml] view plaincopy
- <system.web>
- <sessionState mode="SQLServer" sqlConnectionString="Data Source=127.0.0.1;User ID=sa;Password=;" timeout="60"/>
- </system.web>
在測試Session狀態時,有一點需要注意,就是如果我們在程式中沒有給Session任何值,Session狀態是不向資料庫中儲存的。我們隨便給Session一個索引值,運行後,使用查詢分析器來看一下“ASPState”資料庫中兩個表的內容,如下:
ASPStateTempApplications表
ASPStateTempSessions表
為測試頁上顯示的Session內容:
在這裡我們需要解釋一下AppID和SessionID,先看一下下面兩張圖中的SessionID,表ASPStateTempSessions中的SessionID比頁面上多出了8位,就是後面的“64021378”,這段字串其實是表ASPStateTempApplications裡的AppID的十六進位表示,可以看出資料庫中SessionID的值,是“頁面SessionID+AppID”組合而成的。
既然我們要實現的是跨站共用Session,那麼我們需要建立另外一個測試網站2,也按照上述方法把Session狀態儲存到資料庫中,顯示了在瀏覽器中訪問這兩個網站後,“ASPStateTempSessions”表儲存的Session資訊:
這兩條SessionID前面的部分相同,不同的地方是後面8位標識AppID的值不同,在ASPState庫中,判斷是否為同一使用者是根據SessionID為條件的,雖然這裡使用者是同一人,但訪問的網站不同,SessionID也就不相同了。下面我們要做的就是忽略SessionID裡面的網站標識,這樣就ASPState就可以把來自同一使用者的多個網站訪問當做是同一網站訪問,Session值也就可以在多個網站共用了。
在ASPState庫裡,我們需要修改“TempGetAppID”這個預存程序,把裡面兩句“WHERE AppName = @appName”注釋掉就可以了。在這裡,應注意修改完預存程序後,需要把ASP.NET網站程式重新啟動一下。
[c-sharp] view plaincopy
- ALTER PROCEDURE dbo.TempGetAppID
- @appName tAppName,
- @appId int OUTPUT
- AS
- SET @appName = LOWER(@appName)
- SET @appId = NULL
-
- SELECT @appId = AppId
- FROM [ASPState].dbo.ASPStateTempApplications
- --WHERE AppName = @appName
-
- IF @appId IS NULL BEGIN
- BEGIN TRAN
-
- SELECT @appId = AppId
- FROM [ASPState].dbo.ASPStateTempApplications WITH (TABLOCKX)
- --WHERE AppName = @appName
-
- IF @appId IS NULL
- BEGIN
- EXEC GetHashCode @appName, @appId OUTPUT
-
- INSERT [ASPState].dbo.ASPStateTempApplications
- VALUES
- (@appId, @appName)
-
- IF @@ERROR = 2627
- BEGIN
- DECLARE @dupApp tAppName
-
- SELECT @dupApp = RTRIM(AppName)
- FROM [ASPState].dbo.ASPStateTempApplications
- WHERE AppId = @appId
-
- RAISERROR(‘SQL session state fatal error: hash-code collision between applications ‘‘%s‘‘ and ‘‘%s‘‘. Please rename the 1st application to resolve the problem.‘,
- 18, 1, @appName, @dupApp)
- END
- END
-
- COMMIT
- END
-
- RETURN 0
好了,現在我們可以測試一下了,在一個網站中給Session賦個值,然後在另一個網站中取一下,是不是可以取出來呢,如果可以,那麼恭喜你,你已經實現了Session共用,應用到你的系統中吧。
- 上一篇FormsAuthentication.SetAuthCookie
- 下一篇Session.Abandon和Session.Clear有何不同 (轉)
-
頂
-
0
-
踩
使用SQL Server儲存Session狀態,實現單點登入