Облегченный подход заключается в создании токена, который может самостоятельно проверяться с использованием HMAC. На сервере вы сгенерируете токен с помощью скажем generate_token($secret)
и отправьте это клиенту. Клиент должен включить токен в свой ответ. Проверьте токен на сервере с помощью valid_token($secret, $token)
,
Чтобы предотвратить повторное использование токенов, вы должны хранить потраченные токены. Например, вы можете сохранить использованные токены в db-записи с уникальным ограничением перед выполнением запроса. Если вставка не удалась в ограничении, вы знаете, что токен был использован повторно.
Пример генерации и проверки токена:
function generate_token($secret) {
return build_token($secret, bin2hex(random_bytes(5)));
}
function build_token($secret, $id) {
return $id . '-' . hash_hmac('ripemd160', $id, $secret);
}
function valid_token($secret, $token) {
$parts = explode('-', $token);
return $token === build_token($secret, $parts[0]);
}
Есть и другие способы. Вы можете генерировать случайные идентификаторы и хранить их. Затем удалите их из магазина, как только они будут использованы. Тогда тебе не нужен секрет. Я предпочитаю хранить потраченные токены, потому что до последнего шага в нем нет состояния.
Изменить: Обратите внимание, что для защиты от CSRF токен должен включать в себя идентификатор пользователя. В PHP session_id()
часто можно использовать для этого. Очень упрощенный подход позволил бы session_id()
в $secret
как в generate_token($secret . session_id())
а также valid_token($secret . session_id(), $token)
, Я надеюсь, вы поняли идею.
Других решений пока нет …