8000 Add documentation to overwrite token widget block using esi by alexander-schranz · Pull Request #10867 · symfony/symfony-docs · GitHub
[go: up one dir, main page]

Skip to content

Add documentation to overwrite token widget block using esi #10867

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 38 additions & 1 deletion http_cache/form_csrf_caching.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 CS 8000 RF token, you can use more advanced caching
techniques like :doc:`ESI fragments </http_cache/esi>`, 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(
'<input type="hidden" id="%s__token" name="%s[_token]" value="%s" />',
$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.
Expand Down
0