diff --git a/http_cache/form_csrf_caching.rst b/http_cache/form_csrf_caching.rst index 41aba4c0eab..abea53b988d 100644 --- a/http_cache/form_csrf_caching.rst +++ b/http_cache/form_csrf_caching.rst @@ -30,7 +30,44 @@ How to Cache Most of the Page and still be able to Use CSRF Protection To cache a page that contains a CSRF token, you can use more advanced caching techniques like :doc:`ESI fragments `, where you cache the full -page and embedding the form inside an ESI tag with no cache at all. +page and embedding the form or just the CSRF token inside an ESI tag with no +cache at all. When you have your custom form theme you can do this by create a +new token_widget block and call render_esi there: + +.. code-block:: twig + + {%- block token_widget %} + {{ render_esi(controller('App\\Controller\\FormController::token', { 'form': form.parent.vars.name })) }} + {%- endblock token_widget -%} + +You can use the ``security.csrf.token_manager`` service to generate a token for your given form: + +.. code-block:: php + + public function token(Request $request, TokenGeneratorInterface $generator) + { + $formName = $request->attributes->get('form'); + $csrfToken = $csrfTokenManager->getToken($formName)->getValue(); + + $response = new Response(sprintf( + '', + $formName, + $formName, + $csrfToken + )); + + // In some cases you have a response listener maybe which will set cache headers + // automatically most kind of this listener will not set it if cache headers exist + // so add the following if you want to be sure the response is not cached: + $response->setPrivate(); + $response->setSharedMaxAge(0); + $response->setMaxAge(0); + $response->headers->addCacheControlDirective('must-revalidate', true); + $response->headers->addCacheControlDirective('no-cache', true); + $response->headers->addCacheControlDirective('no-store', true); + + return $response; + } Another option would be to load the form via an uncached AJAX request, but cache the rest of the HTML response.
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: