Как предотвратить множественные логины на веб-сайте PHP

Я хочу предотвратить множественные логины в приложении php.

Во-первых, я создаю статус входа (активный, неактивный) в пользовательской таблице.

Когда пользователь A регистрирует статус пользователя, будет установлен «активный», и если пользователь выйдет из системы, статус будет установлен на «notactive». Когда другой клиент пытается войти в систему с использованием той же самой учетной записи пользователя, я проверяю таблицу пользователя. Если пользователь по-прежнему активен, логин ошибки будет отправлен пользователю.

Проблема возникла, если пользователь закрыл браузер, статус в таблице пользователя может быть обновлен, потому что пользователь не нажал кнопку выхода из системы.

Есть ли у вас какие-либо предложения по этому поводу?

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

Я рекомендую вам сделать следующее:

Во-первых, создайте хэш, чтобы однозначно идентифицировать пользователя при каждом входе в систему. Я бы предположил, что sha1 time() будет достаточно, чтобы избежать столкновений. Независимо от того, что вы выберете, убедитесь, что он достаточно разнообразен, чтобы другой пользователь регистрировался с невероятно низкой вероятностью получения одного и того же хэша (например, не хешируйте IP-адрес или пользовательский агент браузера, поскольку они не меняются достаточно).

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

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

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

Например:

 function authenticateUser($id, $hash, $databaseLink) { # SQL $sql = 'SELECT EXISTS( SELECT 1 FROM `tbl_users` WHERE `id` = \''.mysql_real_escape_string($id).'\' AND `hash` = \''.mysql_real_escape_string($hash).'\' LIMIT 1 );'; # Run Query if ($query = mysql_query($sql, $databaseLink)) { # Get the first row of the results # Assuming 'id' is your primary key, there # should only ever be one row anyway. $result = mysql_fetch_row($query); # Casting to boolean isn't strictly necessary here # its included to indicate the mysql result should # only ever been 1 or 0. return (bool)($result[0]); } else { # Query error :( return false; } } 

Затем мы просто передаем authenticateUser() ID пользователя, hash (за ваши данные сеанса) и database link на базу database link (для подключения к базе данных, которое вам нужно будет открыть ранее).

Если authenticateUser() возвращает true , пользователь аутентифицируется. Если false , пользователь не является ИЛИ база данных недоступна или имеется ошибка SQL.

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

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

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

Если это не сделано с помощью javascript, вы можете проверить при входе в систему, если пользователь был активен последние 15 минут. Если нет, вы можете войти в систему как новый пользователь.

Вы также можете сделать это с помощью javascript. Сделайте вызов ajax, который срабатывает каждую минуту или около того.

 <script> setInterval(function() { // do the ajax call }, 60000); </script> 

Позвольте этому вызову перейти к скрипту, который отредактирует штамп lastonline в db пользователя. При попытке войти в систему вы проверяете пользователя db, если марка lastonline превысила минута, и у вас есть чек, если вы можете войти в систему. Это поможет, когда вы находитесь на странице, но вы не активны последние 15 минут, и вы не хотите, чтобы кто-то еще заходил в систему.

Вы можете изменить свою модель, чтобы войти в систему мог только самый последний пользователь.

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

Для обычного пользователя все кажется «просто работать». Если вы хотите запретить «ненормальным» пользователям распространять свои учетные данные, это должно стать препятствием.

Вот решение, которое не требует постоянного доступа к базе данных для работы …

(что позволит избежать необходимости проверять session_id () на значение базы данных каждый раз, когда вы запрашиваете / обновляете страницу, снимая стресс db / server) …

1. При входе в систему захватите уже существующий session_id, хранящийся в БД для этого пользователя, и выполните следующее:

 session_id("the pre-existing session id in the database goes here"); session_start(); session_destroy(); 

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

Попробуйте и дайте мне знать, если это трюк!

Вам нужно создать уникальный идентификатор и сохранить его в базе данных. То, что я сделал, тоже создавалось. Я храню один в переменной сеанса и использую это, чтобы предотвратить захват сеанса, а другой в базе данных, чтобы предотвратить несколько логинов. Следующий код создаст уникальный идентификатор:

 $unique_id = sha1('xzr4'.gethostbyaddr($_SERVER['REMOTE_ADDR']).$random_string.$_SERVER['HTTP_USER_AGENT'].'f8k2'); 

Если уникальный идентификатор не совпадает, вы просто регистрируете пользователя.

Использование javascript на стороне клиента для отслеживания входа в систему является ненадежным.

Вы можете получить тот же результат, просто создав поле lastlogindate в db и обновив его с последней меткой времени входа пользователя.

При каждой попытке входа в систему, если now () – $ lastlogindate> predefined_timeout, вы должны принять новый логин, иначе откажитесь от него.