2013-07-07 56 views
10

中,每個用戶只有一個併發登錄是可以在Asp.Net Web應用程序中允許每個用戶只有一個併發登錄?在Asp.net

我正在研究一個Web應用程序,我想確保該網站一次只允許一個用戶登錄。如何檢查當前用戶是否已經登錄。

建議我們可以處理這個問題的正確登錄方法。我認爲我們應該使用sql server會話狀態來處理這個問題。你有什麼建議?

我認爲它的一個解決方案。我不知道這是否合適。我們可以這樣做:

  1. 當用戶登錄到系統後,我們將會話ID插入到用戶列中。 (我們將使用數據庫會話,以便我們可以輕鬆獲得所有與會話相關的數據,例如isexpired,expiredatetime等)。

  2. 當同一用戶第二次嘗試登錄時,我們將檢查該會話ID列並檢查該會話是否已過期。如果會話未過期,我們將不允許用戶登錄。

  3. 每次用戶註銷時都更新用戶會話ID。

請推薦這種正確的方式。

+0

您使用的是什麼樣的身份驗證?標準表單Auth或定製的東西? –

+0

我們創建了登錄表單並使存儲過程檢查用戶登錄憑證。我們沒有使用任何會員特徵。 –

+0

保存一個'isLoggedIn'屬性,當你認證時把它提升到'1',當註銷到'0'時,如果會話在此期間結束,你需要重置所有,'Membership'使用'LastLoginDate',你可以播放一下用它。 – balexandre

回答

9

請參考:

When the same user ID is trying to log in on multiple devices, how do I kill the session on the other device?

開箱,.NET不支持此。 .NET允許併發登錄,因爲我相信你知道。

我有同樣的確切需求,並用非常漂亮的解決方案,在上面的鏈接證明了上來。簡而言之,我的要求是一次只能有一個用戶登錄。如果相同的用戶標識嘗試在其他地方登錄,則通過在不同的會話標識下檢查現有的登錄來終止第一次登錄的會話(這可以使用戶標識從其多個實例登錄他們的計算機上的Web瀏覽器[相同的會話ID],這是常見的,但不是來自不同的計算機[不同的會話ID](可能是由於某人偷了他們的憑證)。通過修改代碼,您可能會改變這種行爲 - 即阻止第二次登錄嘗試而不是查殺已經激活並正在使用的第一個登錄。

當然,它可能不適合100%你需要什麼,可以隨意修改它以滿足您的需求。

4

您可以爲每個用戶創建一個緩存條目並將其會話ID存儲在其中。會話ID將在每個瀏覽器會話中唯一。在您的登錄頁面,您可以創建一個緩存條目,當他們成功登錄:

if(Cache.ContainsKey["Login_" + username]) 
    // Handle "Another session exists" case here 
else 
    Cache.Add("Login_" + username, this.Session.SessionID); 

(。守則文本框中鍵入不通過語法檢查假定「僞代碼」)

在Global.asax中,你可以然後掛接到Session_End並使該用戶的緩存條目到期。 global.asax事件的See this

if(Cache.ContainsKey["Login_" + username]) 
    Cache.Remove("Login_" + username); 
+0

爲什麼使用'Cache'而不是'Application'?或者只是全局靜態的'Dictionary'。 – abatishchev

+2

@abatishchev緩存管理得更好,可以通過web farm或多線程進行負載平衡等同步。其他(靜態或應用程序)僅在此過程中,並不保證單例對象在這些情況下。但是,如果案件不需要,您可以使用靜態字典或應用程序對象。 – Tombala

+0

緩存***未分發***,只在Web服務器中,而不在webfarm中。 ***分佈式緩存***適用於所有webfarm。 – Kiquenet

1

登錄憑據存儲在cookie的,所以知道如果用戶登錄,你需要保持對服務器此信息,者優先的數據庫,因爲數據庫可以中唯一共同的地方網絡花園或網絡農場。

你可以保留什麼,在表上,該user A已登錄與否,這將被註銷標誌,也許最後用戶交互有暫停,等...

所以我們說即用戶A已登錄,然後在該數據庫上爲該用戶打開一個標誌,該標誌現在已登錄,如果再次嘗試登錄,則將他拒之門外。 要完成這項工作,您需要向用戶說出註銷或保持超時狀態,類似於超出憑證的時間。

2

你可以在指示用戶當前登錄的用戶表中添加標誌列。

當用戶試圖登錄您檢查標誌,如果這是真的(用戶帳戶已經目前使用),那麼您不允許新用戶登錄,如果該標記爲false,則允許用戶登錄,因爲此時其他人尚未使用帳戶。

請注意,除非用戶主動註銷,否則無法知道用戶何時轉到其他網站(轉到其他網站或關閉瀏覽器等),因此您需要設置某種會話超時如果在指定的時間段內沒有新的請求,將自動註銷用戶。

這意味着,如果用戶關閉他/她的瀏覽器並嘗試登錄移動設備,他/她將無法登錄,直到您指定的會話超時結束,因此暫停一下因爲您不希望用戶快速註銷(如果他/她正在閱讀長頁面等),並且您不希望用戶無法在其他設備上登錄數小時他/她在離開家之前忘了退出。

+1

我認爲你可能不想堅持這樣的數據,但保存在內存中(我會使用全局靜態字典)。你在應用程序還活着的時候在意一旦消失,你不再在乎,所以不需要堅持。此外,還想回來的用戶和正確的未清除數據庫記錄的問題。 – abatishchev

+1

侷限性:全局靜態在Web場景中不起作用。如果會話很粘,則可以啓動另一個會話,並且如果它「堅持」到場中的其他服務器,則兩者都將被允許。沒有粘性會話,全局靜態會在其他服務器上不更新。全球統計也必須與競賽狀況隔離開來,特別是當應用程序易於出現「搶地」登錄浪涌時,大量用戶需要/想要同時登錄(例如,熱門活動門票註冊從指定時開始時間) – BrianCooksey