2014-10-14 3 views
2

Мне нужно ограничить только один вход таким образом, чтобы пользователь не мог войти в систему с помощью одной учетной записи несколько раз одновременно. Также пользователь может быть зарегистрирован на другом сервере, поэтому я не могу использовать session_destroy, мне нужно удалить сеанс «вручную».Удаление сеанса memcache с удаленного сервера

При использовании сеанса с файловым хранилищем он отлично работает, я удаляю файл, логин нового пользователя все отлично работает. Однако, когда я использую сеансы с 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... 

Любая идея, что может быть не так?

+0

Ваш процесс регистрации и сеанса/хранения memcache немного неясен. Больше фрагментов кода/объяснений? – ToBe

+0

@ToBe Login - простая запись переменной сеанса в true. Хранение сеанса Memcache изменяется в php.ini, изменяя 'session.save_handler' и' session.save_path'. Кроме того, я узнал об этом ** Когда страница будет заполнена, она будет толкать данные в сеансе на memcached. Этот последний шаг очень важен, потому что это то, что контролирует истечение данных в memcached. ** Найдено [здесь] (http://blog.preinheimer.com/index.php?/archives/334-Storing-Sessions- in-Memcache-how-everything-behaves.html) – Dexa

+0

Вы проверили, что ваш сеанс с использованием memcache действительно работает? Если есть сомнения, создайте очень маленький файл PHP, чтобы исключить какие-либо ошибки в вашем коде и попробовать там с одной переменной сеанса. – ToBe

ответ

2

Проверьте идентификатор сессии против того, что хранится в базе данных

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

С вашего вопроса я вижу, что в вашей базе данных есть таблица с именем activeLogins, содержащая при сдаче этих полей:и userEmail.

Из этого я предполагаю, что это адрес электронной почты, который однозначно идентифицирует пользователя. Поэтому после нового входа у вас есть $session_id, $safeEmail и соответствующая обновленная строка в таблице activeLogins.

Теперь предположим, что пользователь не вышел из старой машины? Что произойдет при загрузке следующей страницы (перед обновлением таблицы activeLogins)? Правильно, activeSession будет отличаться от $session_id на этом сервере. Помните, что новый логин изменил его.

Итак, все, что вам нужно сделать, это проверить, соответствует ли $session_idactiveSession в таблице activeLogins.

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

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

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

Существует Ratchet (http://socketo.me), это дает вам возможность постоянного соединения. Вы можете просто удалить соединение, когда обнаружен другой логин и реагируют на него в старом клиенте.

Там также высокоуровневый интерфейс для передачи событий от сервера к клиенту:

https://developer.mozilla.org/en-US/docs/Server-sent_events/Using_server-sent_events

Но это не поддерживается в IE, так что вообще не годны к употреблению.

Вы также можете посмотреть на http://pusher.com

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

+0

Благодарим вас за ответ, мне действительно нужно немедленно выйти из системы (+/- несколько секунд), а не только на загрузку страницы, но я думаю, что я мог бы использовать то, что вы сказали в запросе ajax тоже ... Codebase намного больше и больше сложный, чем в примере, который я представил, но я хотел сузить его. Я не использую точный код на каждой загрузке страницы, он используется только при входе в систему. Простой ответ, но я не думал в этом направлении, я буду считать, спасибо. – Dexa

+0

А, я вижу.Ну, нет надежного способа управления браузером на клиентской машине. Но если предположить, что пользователь имеет и оставляет Javascript, вы можете использовать регулярные вызовы ajax (раз в минуту?), Чтобы проверить, что session_id не изменился. Если у вас есть, вы можете удалить последнюю загруженную страницу и показать сообщение «Записано в другой клиент». Также убедитесь, что он удален из истории браузера/кеша. И интернет-соединение должно быть живым, конечно, для того, чтобы это работало. –

+0

Другим методом будет использование Javascript для проверки того, что пользователь что-либо делает. Если они ничего не сделали в течение некоторого времени, вы можете удалить загруженную страницу. Таким образом, вы зависите только от Javascript, а не от интернет-соединения. Это не приятно для пользователя. Вы можете ограничить его только критическим содержимым страницы. –

Смежные вопросы