Вы можете заставить свое приложение хранить токен CSRF в сеансе вместо cook ie, установив для свойства enableCsrfCookie
компонента yii\web\Request
значение false
. Вы можете сделать это в своей сети. php config:
$config = [
// ...
'components' => [
'request' => [
'enableCsrfCookie' => false,
],
// ...
],
// ...
];
Но это заставит приложение запускать сеанс для каждого запроса. Также сеансы по умолчанию используют файлы cookie для хранения идентификатора сеанса, поэтому, в конце концов, это может не сильно улучшить, если вы хотите избежать использования файлов cookie.
Вы также можете расширить yii\web\Request
и переопределить его методы generateCsrfToken()
и loadCsrfToken()
использовать другое хранилище для токена. Но помните, что по умолчанию нет способа узнать, какие запросы поступили из одного сеанса. Необходимо сохранить какой-то идентификатор sessionId в клиенте, а затем отправить его обратно на сервер, чтобы можно было связать запрос, отправляющий форму, с токеном CSRF и запросом, сгенерировавшим токен CSRF.
Другая возможность отключить стандартную защиту CSRF и реализовать собственную защиту формы. Например, вы можете сохранить некоторый секретный ключ в настройках приложения. Затем при создании формы вы будете использовать метод yii\base\Security::hashData()
для добавления временной метки к вашей форме:
$timestamp = Yii::$app->security->hashData(time(), $yourSecurityKey);
Html::hiddenInput('my-csrf', $timestamp);
Затем вы можете проверить ее в действии вашего контроллера:
$timestamp = Yii::$app->security->validateData(
Yii::$app->request->post('my-csrf'),
$yourSecurityKey
);
if ($timestamp === false || $timestamp < (time() - $timeLimitInSeconds)) {
//Do something when CSRF validation is not valid (for example throw bad request exception)
}
// continue form processing
Предупреждение: защита в примере не так безопасна, как стандартная защита CSRF, потому что кто-то может запросить форму из вашего приложения для получения сгенерированного токена, чем использовать токен от него в течение ограниченного времени в форме, отправленной с их сайта.