Кеширование страниц, содержащих CSRF-защищённые формы

Кеширование страниц, содержащих CSRF-защищённые формы

Токены CSRF должны быть разными для каждого пользоватея. Поэтому вам надо быть осторожными, если вы пытаетесь кешировать страницы с формами, которые их имеют.

Чтобы получить больше информации о том, как работает CSRF-защита в Symfony, посмотрите CSRF-защита.

Почему кеширование страниц с CSRF-токеном проблематично

Обычно, каждому пользователю назначается уникальный CSRF-токен, который хранится в сессии для валидации. Это означает, что если вы кешируете страницу с формой, содержащей CSRF-токен, то вы кешируете CSRF-токен только первого пользоваеля. Когда пользователь отправляет форму, токен не будет совпадать с токеном, хранящимся в сессии, и все пользователи (кроме первого) не пройдут CSRF-валидацию при отправке формы.

На самом деле, многие обратные прокси (вроде Varnish) откажутся кешировать страницу с CSRF-токеном. Это потому, что для того, чтобы сохранить PHP-сессию открытой отправляется cookie, а поведение Varnish по умолчанию - не кешировать HTTP-запросы с cookie.

Как кешировать большую часть страницы и иметь возможность использовать CSRF-защиту

Чтобы кешировать страницу, содержащую CSRF-токен, вы можете использовать более продвинутые техники кеширования, вроде ESI-фрагментов, где вы можете кешировать всю страницу, и встраивание формы внутрь ESI-тега без кеша вообще.

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

Или вы даже можете загружать только CSRF-токен с помощью AJAX-запроса и заменять им значение поля формы. Прочтите hinclude.js, чтобы увидеть хорошее решение.