View as Markdown

Logout Link

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

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

Installation

Note

Available since UX Toolkit 3.4.

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:

templates/components/LogoutLink.html.twig
{% props
    ## string|null The firewall name to log out from; when null, the current firewall is used.
    firewall = null
%}

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

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

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.

100%
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.