Определить, существует ли session_id(some-id)
Возможный дубликат:
Определить, существует ли PHP-сессия
Руководство по PHP, похоже, не предоставляет средства для проверки того, session_id
существует. Например, session_id()
имеет дополнительный id
параметр, но это заменяет существующий id
в отличие от поиска нужного метода: session_id_exists(some-id)
Зачем мне проверять, является ли данный session_id
существует? Вариант использования - это служба спортивной подписки, в которой обмен паролями стал проблемой. При входе в систему я сохраняю идентификатор сеанса пользователя в БД и использую его для сравнения с любыми другими существующими идентификаторами сеансов, привязанными к данному userID
,
Для реализации мне нужно проверить, существуют ли собранные идентификаторы сеанса в текущем сеансе (доказательство того, что совместное использование паролей было зарегистрировано более чем одним пользователем одновременно).
Я предполагаю, что есть простой способ достичь этого...
4 ответа
Прежде всего, это было хорошее исследование способов предотвратить совместное использование паролей.
Моя внутренняя реакция на отслеживание активности пользователей по каждому запросу (то есть решение с двумя запросами, предложенное @DaveRandom) была аххххх, нет! Как указывает @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). Вы не можете получить session_id, не связанный с сеансом текущего пользователя, но вы можете сохранить идентификатор сеанса данного пользователя и получить доступ к файлу сеанса, в котором хранится их сеанс из сеанса любого пользователя (включая удаление файла). Ключ имеет идентификатор сеанса для поиска соответствующего файла /path/to/session
Как насчет того, чтобы сделать что-то подобное в верхней части 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('Y-m-d H:i:s', time() - 1200)."'"));
if ($result['current_sessions'] > 1) {
// handle duplicates here
}
Вам может не понравиться этот подход, так как он включает два запроса БД при каждой загрузке страницы, но он должен работать и, вероятно, будет более эффективным, чем проверка файлов сеанса.
Следующий комментарий CodeCaster:
Вместо того, чтобы проверять идентификаторы сеанса PHP, вы должны для каждого подключения пользователя / отключения и окончания сеанса вести список текущих подключенных пользователей (вместе с временем подключения, IP и т. Д., Возможно), например, в таблице БД.
Таким образом, вы сможете обнаружить несколько соединений с одной учетной записью.
Вы также можете попытаться создать небольшой сценарий, повторяющийся по всем файлам сеанса (если вы используете хранилище по умолчанию), использовать "unserialize()" и проверить, имеют ли несколько файлов сеанса одинаковые идентификаторы пользователя (при условии, что вы сохраняете их). в $_SESSION
)
РЕДАКТИРОВАТЬ: так как это должно быть сделано для каждого подключения пользователя, подход таблицы БД (например, что предлагает CodeCaster) кажется лучше.
Вы должны создать свою собственную реализацию Session State, которая предлагает интерфейс для действий, которые вы должны иметь для своего варианта использования.
class SessionState
{
public function idExists($id)
{
$gateway = new SessionGateway();
$result = $gateways->searchById($id);
# ...
}
}
Если вы реализовали детали, вы можете просто использовать объект (ы) в вашем приложении.