2013-07-07 1 views
10

Можно ли разрешить только один одновременный вход для пользователя в веб-приложении Asp.Net?Только один одновременный вход для пользователя в Asp.net

Я работаю над одним веб-приложением, в котором я хочу убедиться, что веб-сайт позволяет только один логин на пользователя за раз. Как проверить, что текущий пользователь уже зарегистрировался или нет.

предлагать правильный метод входа, с помощью которого мы можем справиться с этой проблемой. Я думаю, мы должны использовать состояние сеанса SQL Server для решения этой проблемы. что вы предлагаете?

Я думал, что это решение. Я не знаю, правильно это или нет. мы можем сделать что-то вроде:

  1. При входе пользователя в систему мы вставляем идентификатор сеанса в столбец пользователя. (мы будем использовать сеанс базы данных, чтобы мы могли легко получить все связанные с сеансом данные, например isexpired, expiredatetime и т. д.).

  2. Когда тот же пользователь попытается войти в систему второй раз, мы проверим этот столбец идентификатора сеанса и проверьте, что сессия уже истек. если сеанс не истек, мы не разрешаем пользователю входить в систему.

  3. Обновить идентификатор сеанса пользователя каждый раз, когда пользователь выходит из системы.

Пожалуйста, предложите этот правильный способ или нет.

+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 допускает одновременные входы в систему, так как я уверен, что вы знаете.

У меня было такое же точное требование, и вышло с довольно гладким решением, показанным в приведенной выше ссылке. В двух словах, мое требование состояло в том, чтобы только один вход пользователя в систему происходил за один раз. Если тот же идентификатор пользователя попытался войти в другое место, он убил сеанс для первого входа в систему, проверив наличие существующего входа в систему под другим идентификатором сеанса (это позволило идентификатору пользователя войти в систему из нескольких экземпляров их веб-браузер на своем компьютере [тот же самый идентификатор сеанса], который является общим, но не с другого компьютера [другой идентификатор сеанса] (возможно, из-за того, кто украл их учетные данные, например)). Благодаря модификации кода вы, вероятно, можете изменить поведение этого, т. Е. Предотвратить вторую попытку входа в систему вместо того, чтобы убить первый вход, который уже активен и используется.

Конечно, он может не соответствовать 100% тому, что вам нужно, поэтому не стесняйтесь изменять его в соответствии с вашими потребностями.

4

Вы можете создать запись кэша для каждого пользователя и сохранить в нем свой идентификатор сеанса. Идентификатор сеанса будет уникальным для каждого сеанса браузера. На странице входа в систему, вы можете создать эту запись в кэше, когда они успешно войти в систему:

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

(.. Код набран в текстовом поле без проверки синтаксиса Предположим, «псевдо-код»)

В global.asax вы можете затем подключитесь к Session_End и завершите запись этого кэша пользователя. See this для событий global.asax.

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

Зачем использовать 'Cache' вместо' Application'? Или просто глобальный статический «Словарь». – abatishchev

+2

@abatishchev Cache лучше управляется и может быть синхронизирован между веб-фермами или несколькими потоками с балансировкой нагрузки и т. Д. Остальные (статические или прикладные) находятся только в этом процессе и не будут гарантировать объект singleton в этих случаях. Но, если дело не требует этого, вы можете использовать статический словарь или объект приложения. – Tombala

+0

Кэш *** не распространяется ***, только на веб-сервере, а не в webfarm. *** Распределенный кеш *** для всех webfarm. – Kiquenet

1

учетные данные хранятся на куки, так знать, если пользователь вошел в систему вы должны держать эту информацию на сервере, предпочитаемые в базе данных, так как база данных может быть единственным общим местом среди веб-сад или веб-ферма.

То, что вы можете сохранить, находится на столе, что user A вошел в систему или нет, пометив, что выходит из системы, может быть взаимодействие последнего пользователя, чтобы иметь тайм-аут, и т.д ...

Так пусть говорят что пользователь A, вошел в систему, затем вы открываете флаг в базе данных для этого пользователя, который теперь входит в систему, и если он пытается снова войти в систему, вы его не выпускаете. Чтобы выполнить эту работу, вам нужно либо сказать своим пользователям, чтобы они выходили из системы, либо сохраняли тайм-аут, как и время ожидания учетных данных.

2

Вы можете добавить столбец флаг в таблице пользователя, который указывает, что пользователь в настоящее время вошли в систему.

Когда пользователи пытается войти проверять флаг, если это правда (что счета пользователей уже в настоящее время используется), то вы не разрешаете новому пользователю входить в систему, если флаг является ложным, пользователям разрешено войти в систему, так как в данный момент учетная запись не используется кем-либо еще.

Помните, что если активное использование не выполняется, вы не можете знать, когда пользователи переходят на что-то другое (идет на другой сайт или закрывает браузер и т. Д.), Поэтому вам нужно установить какой-то тайм-аут сеанса, который автоматически выйдет из системы, если в течение указанного периода не будет новых запросов.

Это означает, что если пользователь закрывает свой браузер и пытается зарегистрироваться на мобильном устройстве, например, он/она не сможет войти в систему до истечения указанного таймаута сеанса, поэтому дайте тайм-ауту немного мысли, поскольку вы не хотите, чтобы пользователь быстро выходил из системы (если он читает длинную страницу и т. д.), и вы не хотите, чтобы пользователи не могли входить в систему на другом устройстве часами, если он/она забыл выйти из дома, прежде чем покинуть дом.

+1

Я думаю, вы можете не захотеть сохранить такие данные, но сохранить их в памяти (я бы использовал глобальный статический словарь). Вы заботитесь, пока приложение остается в живых. Как только он уйдет, вам все равно, так что не нужно его упорствовать. Также создайте проблему с возвратом пользователя и должным образом не очищенной записью базы данных. Ограничения – abatishchev

+1

: глобальная статика не работает в сценариях веб-фермы. если сеансы липкие, можно запустить другой сеанс, и если он «прилипает» к другому серверу в ферме, оба будут разрешены. без липких сеансов, глобальная статика не будет обновляться на других серверах. глобальная статика также должна быть изолирована от условий гонки, особенно если приложение подвержено «взлому» входа в сеть, когда поток пользователей должен/должен регистрироваться в одно и то же время (например, регистрация горячих билетов начинается с указанного время) – BrianCooksey

0

Если вы используете систему идентификации, эта ссылка поможет вам как единому логину пользователя на нескольких устройствах. Prevent Multiple Logins in Asp.Net Identity Я пробовал, что они отлично работают в моем проекте Asp.net Mvc.