2013-10-20 174 views
1

我試圖阻止多個記錄我的應用程序,對此我使用這種方法:不要允許用戶多次登錄

在我第一次用戶登錄保存在一個會話的用戶,第二次用戶嘗試再次登錄,我首先檢查會話,如果會話已經有相同的用戶,我不允許用戶再次登錄。

此方法在同一瀏覽器中工作良好,但是如果我嘗試再次登錄同一用戶從另一個瀏覽器,它允許多個登錄,因爲會話中沒有任何內容。

如果我嘗試從其他計算機登錄,則會發生同樣的問題。

請建議。 感謝

這裏是我有

  User user = (User) rdbHelper.getAuthentication(userid, password); 
    if(user!=null) 
    { 
     session=getThreadLocalRequest().getSession(true); 
     User loggedInUser = (User) session.getAttribute("user"); 

     if(user.getId() == loggedInUser.getId()){ 
     user.setId(0); // making user null and stopping user to login 
     }else{ 
     session=getThreadLocalRequest().getSession(true); 
     session.setAttribute("user", user); // allow user to sing in 
     } 
+0

這不能用僅僅一個會話來完成,但是你需要在數據庫中存儲IP地址,並且基於你需要檢查 –

回答

2

下面是步驟,你可以試試要實現這一點:

  • 用戶登錄後立即將其IP地址,他的名字和/或一些隨機生成的令牌存儲在數據庫中的某個表中。
  • 當用戶註銷時,清除表中以前存儲的值。
  • 在登錄過程中,檢查該表以查看錶中是否存在用戶信息,如果信息可用,則表示用戶已從其他計算機,瀏覽器等登錄並拒絕登錄訪問。
  • 如果信息不可用,則允許用戶登錄。

但是,當然,這也不是傻瓜證明,根據你的需要,你可能需要添加adiitional列等

還有一些在這種方法需要被處理,一個一些缺點案例是:

1)如果用戶的PC關閉或用戶不打擾註銷會發生什麼?在這種情況下,用戶將被剝奪訪問權限。

在這種情況下,應該有一些作業在特定的時間間隔進行清理過程。您可能需要在查找表中添加「Timestamp」列,該作業的主要工作是將時間戳與某些預定義的超時值(比如10分鐘)進行比較,並刪除所有這些行。

因此,用戶可以登錄沒有問題。

+0

謝謝,但如果用戶計算機意外關閉,用戶沒有登出自己,用這種方法,我認爲他將永遠無法再次登錄 – junaidp

+0

@junaidp,我編輯:)在這種情況下,應該有一些工作在特定的時間間隔內清理表格,就像會話超時一樣。 –

+0

謝謝:)。這種方法很好,但是你的意思是說,每隔10分鐘就會有一次調用數據庫。即使用戶電腦運行正常,他正在處理我的應用程序。在這種情況下,這個工作正在運行在指定的時間間隔將在10分鐘後進入數據庫,並刪除所有內容即使用戶正在順利使用應用程序(無PC掛起或任何其他),但數據庫表現在清除了,所以...其他用戶可以登錄..我是對的嗎? – junaidp

0

當用戶通過Web瀏覽器做個像正常的會話登錄,然後在數據庫中你的狀態,他們已登錄。當他們嘗試再次登錄您檢查用戶的數據庫,如果他們登錄,不要讓他們在新的頁面上。

當他們註銷你破壞了會議,但你還需要將數據庫設置爲說,他們還沒有登錄,這將阻止人們記錄從不同的瀏覽器

+0

謝謝,但是如果用戶計算機意外關閉或者用戶關閉瀏覽器而沒有輸出日誌用這種方法,我認爲他永遠不能再次登錄 – junaidp

+0

你爲時間添加一個會話變量。這是我如何做到的。如果他們在訪問頁面時設置了時間變量,那麼檢查時間並與時間比較,如果超過x分鐘,則刪除用戶名的會話變量,這將允許他們重新登錄 – NoLiver92

+0

但該事物只應檢查IF x Minutes是不活動的,否則它會清除session/db(即使用戶仍在使用我的應用程序).​​.另一個用戶將能夠登錄,所以多次登錄問題將再次出現 – junaidp

0

您可以在用戶表中添加一個字段名稱爲「IsLoggedIn」的額外字段作爲位字段,並將其設置爲true,直到用戶註銷。一旦用戶註銷,將其設置爲false。這也需要在會話到期時間完成。一旦會話過期,該字段應該使用觸發器或通過SP呼叫自動設置爲false。 當試圖從不同的瀏覽器或計算機登錄時,它應該檢查「IsLoggedIn」字段,如果它已經是真的,如果它不是,讓用戶登錄。

+0

謝謝,你能給我一個想法如何在會話超時時調用分貝,我將如何知道在代碼中會話超時。 – junaidp

0

我們有我們的工作項目類似的情況,我們採取的方法是:

  1. 生成令牌每當用戶登錄,並將其存儲在會話和數據庫此用戶。
  2. 向服務器發送每個請求後,請驗證該令牌,以確保他處於有效會話中,並且在超時後他不再回來。 (任何時間間隔超過15分鐘的請求,我們使令牌無效)
  3. 如果用戶嘗試再次登錄(例如,從不同的瀏覽器或未註銷),我們可以看到該令牌仍然存在該用戶的數據庫,如果他想「殺死」舊會話,我們會向用戶顯示一條警告消息。這樣,即使計算機崩潰或忘記註銷,他也可以決定終止舊會話並繼續新會話。或者他可以取消創建新的令牌以繼續在舊會話中工作。
  4. Ofcourse,如果用戶點擊「註銷」,我們清除令牌
+0

你能否用我的這句話,你是怎麼做到的:即使電腦崩潰或忘記註銷,他也可以決定殺掉舊的會話並繼續新的會話 – junaidp

0

嘗試在servlet上下文中存儲數據。當用戶登錄時

context = getServletContext(); 
List<string> logins = context.getAttribute("logins"); 
logins.add(username); 

檢查登錄可以這樣工作。

context = getServletContext(); 
List<string> logins = context.getAttribute("logins"); 
if (!logins.contains(username)) { 
    login(); 
} else { 
    deny(); 
} 

使用servletContextListener在應用程序啓動時創建列表。

我會使用HttpSessionListener來管理列表。會話結束後,檢查它是否已登錄,並從列表中刪除登錄名。