Как удалить неиспользуемые токены безопасности из массива

У меня есть проблема, и я не могу найти какое-либо решение. Проблема в том, что когда пользователь открывает страницу, токен безопасности генерируется таким образом и добавляется в массив SESSION.

$token = generate_csrf_token();
$_SESSION['tokens'][] = $token;

Я использую этот токен $ в отправке формы в качестве скрытого ввода для безопасности CSRF. Теперь проблема в том, что если пользователь публикует какой-либо комментарий, я могу удалить токен $ из массива после того, как комментарий будет опубликован следующим образом.

$token = $_POST['token'];

// comment posting process

$key = array_search($token, $_SESSION['tokens']);
unset($_SESSION['tokens'][$key]);

Но если пользователь не публикует никаких комментариев и не покидает страницу, как я могу удалить этот токен $ из массива $_SESSION['tokens'][]. Если я не удалю, это может привести к большому количеству неиспользуемых токенов $ в массиве.


person Munib    schedule 29.04.2013    source источник
comment
Когда вы убиваете сессию?   -  person hemc4    schedule 29.04.2013


Ответы (2)


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

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

Таким образом, вам не нужно беспокоиться об «Очищении маркеров безопасности», когда пользователь покидает страницу. Об этом позаботятся автоматически. Если, конечно, вы сами не облажались с управлением сессиями. См. настройки сеанса, чтобы узнать, какие параметры можно изменить.

Теперь, если ваша цель — очистить токены, пока пользователь все еще находится на странице, используя тот же сеанс, есть несколько вариантов.

Во-первых, использовать один токен безопасности на сеанс. Если пользователь закрывает страницу (читай: загружает другую страницу на вашем сайте), то он выдает новый токен в $_SESSION['token'] (без массива), а старый очищается. Это требует, чтобы вы проверили токен после POST, прежде чем менять его.

Другой вариант — оставить только последние 5 или около того токенов. Тогда вы сможете содержать его в чистоте, не изменяя проверку токенов. Для этого вы можете использовать array_shift.

<?
$tokens[] = 'new token';
if (count($tokens)>5) {
  array_shift($tokens); //first is removed, so the last 5 remain
}
?>

Последний способ, который я могу придумать, это добавить время к токену и при запросе страницы перебрать все токены и проверить время. Если время прошло более xx минут, удалите его.

person Hugo Delsing    schedule 29.04.2013

Как и в случае любого асинхронного состояния клиент-сервер, ответ — тайм-ауты. Вы не можете гарантировать, что токен когда-либо будет использоваться, и даже если он в конечном итоге будет использован, вы не можете знать, когда. Также нет явного механизма обратной связи для неиспользованных токенов; неиспользованные токены просто никогда не используются.

Таким образом, свяжите временную метку с каждым токеном. Периодически вы проверяете все сохраненные токены и удаляете те, которые считаете просроченными. Выберите разумный срок экспирации. Например.:

// run garbage collection roughly every 100 page loads
if (mt_rand(0, 100) == 0) {
    foreach ($_SESSION['tokens'] as $i => $token) {
        if ($token['timestamp'] < time() - 3600) {
            unset($_SESSION['tokens'][$i]);
        }
    }
}

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

person deceze♦    schedule 29.04.2013