2013-07-07 18 views
10

jest możliwe, aby zezwolić na tylko jedno współbieżne logowanie na użytkownika w aplikacji internetowej Asp.Net?Tylko jedno równoczesne logowanie na użytkownika w Asp.net

Pracuję nad jedną aplikacją internetową, w której chcę się upewnić, że witryna dopuszcza tylko jedno logowanie na użytkownika na raz. Jak sprawdzić, czy bieżący użytkownik jest już zalogowany, czy nie.

sugerują właściwą metodę logowania, dzięki której poradzimy sobie z tym problemem. Myślę, że powinniśmy użyć stanu sesji serwera SQL, aby rozwiązać ten problem. co sugerujesz ?

Pomyślałem o jednym rozwiązaniu. nie wiem, czy to właściwe, czy nie. możemy zrobić coś takiego:

  1. Po zalogowaniu użytkownika do systemu wstawiamy identyfikator sesji w kolumnie użytkownika. (wykorzystamy sesję bazy danych, aby łatwo uzyskać wszystkie dane związane z sesją, takie jak isexpired, expiredatetime itp.).

  2. Gdy ten sam użytkownik spróbuje się zalogować po raz drugi, sprawdzimy kolumnę identyfikatora sesji i sprawdzimy, czy sesja już wygasła, czy też nie. jeśli sesja nie wygasła, nie zezwalamy użytkownikowi na logowanie.

  3. Zaktualizuj identyfikator sesji użytkownika za każdym razem, gdy użytkownik się wyloguje.

Proszę zasugerować w odpowiedni sposób, czy nie.

+0

Jakiego rodzaju uwierzytelnienia używasz? standardowy formularz Autoryzacja lub coś niestandardowego? –

+0

stworzyliśmy formularz logowania i wykonaliśmy procedurę sklepu, aby sprawdzić dane logowania użytkownika. nie wykorzystaliśmy żadnych funkcji członkostwa. –

+0

zapisz właściwość 'isLoggedIn' i po uwierzytelnieniu podnieś ją do' 1', gdy wylogujesz się do '0', jeśli sesja zakończy się w międzyczasie musisz zresetować wszystko,' Membership' używa 'LastLoginDate' i możesz zagrać trochę z tym. – balexandre

Odpowiedz

9

Patrz:

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

Po wyjęciu z pudełka, .NET nie obsługuje tej funkcji. .NET pozwala na równoczesne logowanie, ponieważ jestem pewien, że jesteś świadomy.

Miałem ten sam dokładny wymóg i wymyśliłem całkiem sprytne rozwiązanie, przedstawione w powyższym linku. Krótko mówiąc, moim wymogiem było jednorazowe zalogowanie się jednego użytkownika. Jeśli ten sam identyfikator użytkownika próbował zalogować się gdzie indziej, to zabił sesję podczas pierwszego logowania, sprawdzając istniejące logowanie w ramach innego identyfikatora sesji (to umożliwiło zalogowanie się ID użytkownika z wielu wystąpień ich przeglądarka internetowa na swoim komputerze [ten sam identyfikator sesji], która jest powszechna, ale nie z innego komputera [inny identyfikator sesji] (prawdopodobnie z powodu kogoś, kto ukradł swoje dane uwierzytelniające, na przykład)). Poprzez modyfikację kodu prawdopodobnie mógłbyś zmienić to zachowanie - tj. Zapobiec drugiej próbie zalogowania zamiast zabicia pierwszego logowania, które jest już aktywne i używane.

Oczywiście, może nie pasować w 100% do tego, czego potrzebujesz, więc możesz go zmodyfikować zgodnie ze swoimi potrzebami.

4

Możesz utworzyć wpis w pamięci podręcznej na użytkownika i zapisać w nim swój identyfikator sesji. Identyfikator sesji będzie unikalny na sesję przeglądarki. Na stronie logowania, można utworzyć ten wpis pamięci podręcznej, gdy pomyślnie zalogować:

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

(.. Kod wpisany w polu tekstowym bez sprawdzenia składni Załóżmy, „pseudo-kod”)

w global.asax można następnie przechwytuj do SessionEnd i wygasnij wpis cache użytkownika. See this dla zdarzeń global.asax.

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

Dlaczego używać 'Cache' zamiast' Application'? Lub po prostu globalny statyczny 'słownik'. – abatishchev

+2

@abatishchev Pamięć podręczna jest lepiej zarządzana i można ją zsynchronizować między farmami sieci Web lub wieloma wątkami z równoważeniem obciążenia itp. Pozostałe (statyczne lub aplikacji) są tylko w trakcie procesu i nie gwarantują pojedynczego obiektu w tych przypadkach. Ale jeśli sprawa nie wymaga tego, możesz użyć statycznego słownika lub obiektu aplikacji. – Tombala

+0

Pamięć podręczna nie jest *** rozprowadzana ***, tylko w serwerze WWW, a nie w webfarmie. *** Rozproszona pamięć podręczna *** jest przeznaczona dla wszystkich webfarmów. – Kiquenet

1

dane logowania są przechowywane w pliku cookie, więc wiedzieć, czy użytkownik jest zalogowany trzeba zachować to informacje na temat serwera, preferowana w bazie danych, ponieważ baza danych może być tylko wspólne miejsce wśród internetowa farma ogrodowa lub internetowa.

Co można zachować, to na stole, że user A jest zalogowany, czy nie, to, że flaga jest wylogowany, może interakcja ostatni użytkownik miał limit czasu, itp ...

Więc powiedzmy że użytkownik A jest zalogowany, to otworzysz flagę w bazie danych dla tego użytkownika, który jest teraz zalogowany, a jeśli spróbujesz się zalogować ponownie, trzymasz go z dala. Aby to zadziałało, musisz albo powiedzieć użytkownikom, aby się wylogowali, albo, aby zachować limit czasu, podobny do czasu oczekiwania na poświadczenia.

2

Można dodać kolumnę flagę w tabeli użytkownika, który wskazuje, że użytkownik jest aktualnie zalogowany.

Gdy użytkownik próbuje się zalogować sprawdzić flagę jeśli to prawda (że użytkownicy konto jest już obecnie stosowane) nie pozwalasz nowemu użytkownikowi na zalogowanie się, jeśli flaga jest fałszywa, użytkownicy mogą się logować, ponieważ konto nie jest używane przez nikogo innego w tym momencie.

Należy jednak pamiętać, że jeśli zastosowania nie są aktywnie wylogowywane, użytkownik nie może wiedzieć, kiedy użytkownicy przechodzą do innej strony (przechodzi do innej witryny lub zamyka przeglądarkę itp.), Dlatego należy ustawić limit czasu sesji, automatycznie wyloguje użytkownika, jeśli nie ma nowych żądań w określonym czasie.

Oznacza to, że jeśli użytkownik zamknie przeglądarkę i spróbuje zalogować się na urządzeniu mobilnym, na przykład nie będzie mógł się zalogować, dopóki nie upłynie określony czas oczekiwania na sesję, więc należy podać limit czasu. Myśli, że nie chcesz, aby użytkownik szybko się wylogował (jeśli czyta dłuższą stronę itd.) i nie chcesz, aby użytkownicy nie mogli logować się na inne urządzenie przez wiele godzin, jeśli on/ona zapomniał się wylogować przed opuszczeniem domu.

+1

Myślę, że możesz nie chcieć utrzymywać takich danych, ale przechowywać je w pamięci (użyłbym globalnego statycznego słownika). Dbasz o to, gdy aplikacja działa. Kiedy już odejdzie, nie będziesz już tym przejmować, więc nie musisz tego wytrwać. Również obraz problem z powrotem użytkownika i odpowiednio nie wyczyszczone rekord bazy danych. – abatishchev

+1

ograniczenia: globalne statyczne nie działałyby w scenariuszach farmy internetowej. jeśli sesje są lepkie, można rozpocząć kolejną sesję i jeśli zostanie "przyklejona" do innego serwera w gospodarstwie, obie będą dozwolone. bez sesji klejących globalna statystyka nie byłaby aktualizowana na innych serwerach. globalna statystyka musiałaby być również izolowana przed warunkami wyścigowymi, szczególnie jeśli aplikacja jest podatna na "logowanie się do ziemi", gdzie powódź użytkowników potrzebuje/chce się zalogować w tym samym czasie (np. rejestracja gorących biletów zaczyna się od określonego czas) – BrianCooksey

0

Jeśli korzystasz z systemu identyfikacji, ten link pomoże Ci zalogować się na jednym urządzeniu na wielu urządzeniach. Prevent Multiple Logins in Asp.Net Identity Próbowałem, że działają dobrze w moim projekcie Asp.net Mvc.

Powiązane problemy