Возможный дубликат:
Обнаруживать, существует ли сеанс PHP
Руководство по PHP, похоже, не дает возможности проверить, существует ли данный session_id
. Например, session_id()
имеет необязательный параметр id
, но заменяет существующий id
а не выполняет поиск желаемого метода: session_id_exists(some-id)
Почему мне нужно проверить, существует ли данный session_id
? Случай использования – это услуга спортивной подписки, в которой совместное использование пароля стало проблемой. При входе я сохраняю идентификатор сеанса пользователя в БД и использую его для сравнения с другими существующими идентификаторами сеанса, прикрепленными к данному userID
.
Чтобы реализовать, мне нужно проверить, существуют ли установленные идентификаторы сеанса в текущем сеансе (доказательство совместного использования паролей – это более одного пользователя, зарегистрированного одновременно).
Я предполагаю, что есть простой способ добиться этого …
Как насчет того, что вы делаете что-то подобное в верхней части index.php
// Update current userid/session record with current timestamp mysql_query("UPDATE sessions SET last_activity = CURRENT_TIMESTAMP() WHERE user = '$username' AND sid = '".session_id()."'"); // Search for multiple records with timestamp in the last 20 minutes where user id is the same $result = mysql_fetch_assoc(mysql_query("SELECT COUNT(*) AS current_sessions FROM sessions WHERE user = '$username' AND last_activity > '".date('Ymd H:i:s', time() - 1200)."'")); if ($result['current_sessions'] > 1) { // handle duplicates here }
Возможно, вам не нравится такой подход, поскольку он включает в себя два запроса БД при каждой загрузке страницы, но он должен работать и, вероятно, будет более эффективным, чем проверка файлов сеанса.
После комментария CodeCaster:
Вместо проверки идентификаторов сеанса PHP вы должны, для каждого подключения пользователя / отключения и окончания сеанса, поддерживать список подключенных в данный момент пользователей (вместе со временем подключения, IP и т. Д.), Например, в таблице БД.
Таким образом, вы сможете обнаруживать множественные соединения с одной учетной записью.
Вы также можете попытаться создать небольшой цикл сценария по всем файлам сеанса (если вы используете хранилище по умолчанию), используйте «unserialize ()» на нем и проверьте, имеют ли несколько файлов сеанса одинаковые идентификаторы пользователя (при условии их сохранения в $_SESSION
)
EDIT : поскольку это должно быть сделано для каждого пользовательского соединения, подход таблицы БД (например, что предлагает CodeCaster) выглядит лучше.
Вы должны создать свою собственную реализацию состояния сеанса, которая предлагает интерфейс для действий (действий), необходимых для вашего прецедента.
class SessionState { public function idExists($id) { $gateway = new SessionGateway(); $result = $gateways->searchById($id); # ... } }
Если вы внедрили детали, вы можете просто использовать объекты в своем приложении.
Прежде всего, это было хорошее исследование способов предотвращения обмена паролями.
Моя реакция на отслеживание активности пользователя на основе запроса (т. Е. Решение с двумя запросами, предложенное @DaveRandom) было ahhhhh, нет! Как отмечает @CodeCaster, вероятный случай преждевременной оптимизации, но эй, у нас есть небольшая (несколько тысяч), но бешеная база пользователей, которая будет очень счастлива с началом сезона хоккея и результатами игры. бегали в течение многих лет, не хотят качать лодку, это платная услуга, поэтому производительность должна быть отличной.
Хорошо, решение:
У пользователя apache есть доступ для чтения / записи к файлам сеанса в каталоге сеанса. Записывая session_id во время входа в систему, у нас есть компоненты для блокировки общих учетных записей паролей. При успешном входе в систему:
- Loop through stored session ids related to target account - if /path/to/session-id-file not empty, increment login counter - if login counter exceeds number of users allowed for a given plan: - delete all session files related to target account - lock the account and force a password reset
Есть минимальные накладные расходы, реализация – торт, проблема решена.
Примечание. Первоначально я думал, что невозможно получить доступ к файлам каталога сеансов без создания цикла безопасности; однако, это не так (по крайней мере, на моем складе CentOS 5 setup). Вы не можете получить session_id, не относящийся к сеансу текущего пользователя, но вы можете сохранить идентификатор сеанса данного пользователя и получить доступ к файлу сеанса, который хранит их сеанс с любого сеанса пользователя (включая выдувание файла). Ключ имеет идентификатор сеанса для поиска соответствующего / path / to / session-файла