View as Markdown

Logout Link

A link that logs the current user out through a secure POST form.

Loading...
<twig:LogoutLink class="">
    Logout
</twig:LogoutLink>

Installation

php bin/console ux:install logout-link --kit common

Install the following Composer dependencies:

composer require symfony/security-bundle symfony/security-csrf

Copy the following file(s) into your app:

{# @prop firewall string|null The firewall name to log out from; when null, the current firewall is used. #}
{# @block content The link label. #}
{% props firewall = null %}

&lt;twig:PostLink {{ ...attributes.defaults({
    href: logout_path(firewall),
    csrfTokenId: &#039;logout&#039;,
}) }}&gt;
    {{ block(outerBlocks.content)|default(&#039;Logout&#039;) }}
&lt;/twig:PostLink&gt;
{# @prop href string The URL the form submits to. #}
{# @prop csrfTokenId string|null The CSRF token ID used to generate the hidden token field; when null, no token is added. #}
{# @prop method string The HTTP method used to submit the form; when not `POST`, a hidden `_method` field is added for method spoofing. #}
{# @prop confirm string|null A confirmation message shown before submitting; when null, no confirmation is required. #}
{# @block content The button label. #}
{% props href, csrfTokenId = null, method = &#039;POST&#039;, confirm = null %}

&lt;form{{ attributes.nested(&#039;form&#039;).defaults({
    action: href,
    method: &#039;post&#039;,
    class: &#039;inline&#039;,
    onsubmit: confirm ? &#039;return confirm(&#039; ~ confirm|json_encode ~ &#039;)&#039; : false,
}) }}&gt;
    {% if method|upper != &#039;POST&#039; %}
        &lt;input type=&quot;hidden&quot; name=&quot;_method&quot; value=&quot;{{ method|upper }}&quot;&gt;
    {% endif %}
    {% if csrfTokenId %}
        &lt;input{{ attributes.nested(&#039;csrf&#039;).defaults({
            type: &#039;hidden&#039;,
            name: &#039;_csrf_token&#039;,
            &#039;data-controller&#039;: &#039;csrf-protection&#039;,
            value: csrf_token(csrfTokenId),
        }) }}&gt;
    {% endif %}
    &lt;button{{ attributes.defaults({type: &#039;submit&#039;}) }}&gt;
        {% block content %}{% endblock %}
    &lt;/button&gt;
&lt;/form&gt;

Usage

<twig:LogoutLink>
    Logout
</twig:LogoutLink>
Warning

LogoutLink logs the user out through a POST request protected by a CSRF token (token id logout). For it to work, your firewall's logout must require POST and have CSRF protection enabled — otherwise logging out will be rejected.

Restrict the logout route to POST so it can't be triggered by a plain link or prefetch:

#[Route('/logout', name: 'app_logout', methods: ['POST'])]
public function logout(): never
{
    throw new \LogicException('This method is intercepted by the logout key on your firewall.');
}

Point the firewall's logout at that route (app_logout) and enable CSRF protection (this validates the logout token the component sends):

# config/packages/security.yaml
security:
    firewalls:
        main:
            logout:
                path: app_logout
                enable_csrf: true

Examples

Specific Firewall

Set the firewall prop to log out from a specific firewall instead of the current one.

Loading...
<twig:LogoutLink firewall="main" class="">
    Logout from the main firewall
</twig:LogoutLink>

API Reference

Prop Type Default
firewall 
string|null null
Block Description
content The link label.