Таким образом, мне нужно ограничить только один вход в систему, чтобы пользователь не мог войти в систему с использованием одной учетной записи одновременно. Также пользователь может войти на другой сервер, поэтому я не могу использовать session_destroy, мне нужно удалить сессию «вручную».
При использовании сеанса с файловым хранилищем все работает нормально, я удаляю файл, захожу новый пользователь все отлично работает. Однако, когда я использую сеансы с memcache, я могу удалить сеанс из memcache, но дальнейший вход в систему в том же запросе теряется.
Вот как я это делаю:
session_regenerate_id();
$session_id = session_id();
$m = new Memcache();
$m->connect('XXX.XXX.XXX.XXX', 11211);
$ans = $m->delete(SESSION_ID_OF_ALREADY_LOGGED_USER);
$query = "UPDATE activeLogins SET activeSession = '{$session_id}' WHERE userEmail = $safeEmail LIMIT 1";
$dbh->exec($query);
//Login new user...
Есть идеи, что может быть не так?
Насколько я понимаю, вы хотите ограничить одного пользователя одной клиентской машиной. И эта машина должна быть последней, на которой был выполнен вход. Я думаю, что вы должны быть в состоянии достичь этого с простой проверкой каждой загрузки страницы.
По вашему вопросу я вижу, что в вашей базе данных есть таблица activeLogins
содержащие по меньшей мере эти поля: activeSession
а также userEmail
,
Исходя из этого, я предполагаю, что это адрес электронной почты, который однозначно идентифицирует пользователя. Таким образом, после нового входа в систему у вас есть $session_id
, $safeEmail
и соответствующая обновленная строка в activeLogins
Таблица.
Теперь предположим, что пользователь не вышел из старой машины? Что произойдет при загрузке следующей страницы (перед обновлением activeLogins
Таблица)? Верно, activeSession
будет отличаться от $session_id
на этом сервере. Помните, что новый логин изменил его.
Так что все, что вам нужно сделать, это проверить, является ли $session_id
соответствует activeSession
в activeLogins
Таблица.
Я также предложил бы только обновить activeLogins
Таблица после нового входа в систему, а не на каждой странице загрузки. Хотя из вашего вопроса не ясно, делаете ли вы это или нет.
Я не уверен, что это действительно отвечает на ваш вопрос. Кажется, такой простой ответ. Однако ваш вопрос не очень понятен. Вы действительно используете код, который вы показываете нам в таком порядке на каждой странице загрузки ?!
В ответ на все ваши ответы я искал лучший способ отправки уведомлений с сервера на клиентский компьютер. Один из методов, которые вы упомянули сами, это опрос ajax, но я думаю, что это плохая практика, и ее не следует использовать.
Есть трещоткаhttp://socketo.me) это дает вам постоянную связь. Вы можете просто удалить соединение при обнаружении другого логина и отреагировать на него в старом клиенте.
Также имеется интерфейс более высокого уровня для отправки событий с сервера на клиент:
https://developer.mozilla.org/en-US/docs/Server-sent_events/Using_server-sent_events
Но это не поддерживается в IE, поэтому обычно его нельзя использовать.
Вы также можете посмотреть на http://pusher.com
Суть всех этих предложений заключается в том, что вы можете эффективно выдавать сигнал клиенту, указывающий, что он должен закрыть доступ к сайту, который вы обслуживаете, без постоянного опроса.
Других решений пока нет …