Skip to content

[Routing][Security] Document the LogoutRouteLoader #19000

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

Merged
merged 1 commit into from
Dec 12, 2023
Merged
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
160 changes: 124 additions & 36 deletions security.rst
Original file line number Diff line number Diff line change
@@ -1796,7 +1796,7 @@ To enable logging out, activate the ``logout`` config parameter under your fire
main:
# ...
logout:
path: app_logout
path: /logout

# where to redirect after logout
# target: app_any_route
@@ -1817,11 +1817,10 @@ To enable logging out, activate the ``logout`` config parameter under your fire
<!-- ... -->

<firewall name="main">
<!-- ... -->
<logout path="app_logout"/>
<logout path="/logout"/>

<!-- use "target" to configure where to redirect after logout
<logout path="app_logout" target="app_any_route"/>
<logout path="/logout" target="app_any_route"/>
-->
</firewall>
</config>
@@ -1838,68 +1837,58 @@ To enable logging out, activate the ``logout`` config parameter under your fire
$mainFirewall = $security->firewall('main');
// ...
$mainFirewall->logout()
// the argument can be either a route name or a path
->path('app_logout')
->path('/logout')

// where to redirect after logout
// ->target('app_any_route')
;
};

Next, you need to create a route for this URL (but not a controller):
Symfony will then un-authenticate users navigating to the configured ``path``,
and redirect them to the configured ``target``.
Comment on lines +1847 to +1848
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Symfony will then un-authenticate users navigating to the configured ``path``,
and redirect them to the configured ``target``.
Symfony will then un-authenticate users navigating to the configured ``path``,
and redirect them to the configured ``target``. You can generate URLs to this
path using the ``_security_<firewallname>`` route name (e.g. ``_security_main``).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn’t the LogoutUrlGenerator be mentioned instead?


.. configuration-block::

.. code-block:: php-attributes
.. tip::

// src/Controller/SecurityController.php
namespace App\Controller;
If you need to reference the logout path, you can use the ``_logout_<firewallname>``
route name (e.g. ``_logout_main``).

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
If your project does not use :ref:`Symfony Flex <symfony-flex>`, make sure
you have imported the logout route loader in your routes:

class SecurityController extends AbstractController
{
#[Route('/logout', name: 'app_logout', methods: ['GET'])]
public function logout(): never
{
// controller can be blank: it will never be called!
throw new \Exception('Don\'t forget to activate logout in security.yaml');
}
}
.. configuration-block::

.. code-block:: yaml

# config/routes.yaml
app_logout:
path: /logout
methods: GET
# config/routes/security.yaml
_symfony_logout:
resource: security.route_loader.logout
type: service

.. code-block:: xml

<!-- config/routes.xml -->
<!-- config/routes/security.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing
https://symfony.com/schema/routing/routing-1.0.xsd">

<route id="app_logout" path="/logout" methods="GET"/>
<import resource="security.route_loader.logout" type="service"/>
</routes>

.. code-block:: php

// config/routes.php
// config/routes/security.php
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;

return function (RoutingConfigurator $routes): void {
$routes->add('app_logout', '/logout')
->methods(['GET'])
;
return static function (RoutingConfigurator $routes): void {
$routes->import('security.route_loader.logout', 'service');
};

That's it! By sending a user to the ``app_logout`` route (i.e. to ``/logout``)
Symfony will un-authenticate the current user and redirect them.
.. versionadded:: 6.4

The :class:`Symfony\\Bundle\\SecurityBundle\\Routing\\LogoutRouteLoader` was
introduced in Symfony 6.4.

Logout programmatically
~~~~~~~~~~~~~~~~~~~~~~~
@@ -1989,6 +1978,105 @@ to execute custom logic::
}
}

Customizing Logout Path
~~~~~~~~~~~~~~~~~~~~~~~

Another option is to configure ``path`` as a route name. This can be useful
if you want logout URIs to be dynamic (e.g. translated according to the
current locale). In that case, you have to create this route yourself:

.. configuration-block::

.. code-block:: yaml

# config/routes.yaml
app_logout:
path:
en: /logout
fr: /deconnexion
methods: GET

.. code-block:: xml

<!-- config/routes.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing
https://symfony.com/schema/routing/routing-1.0.xsd">

<route id="app_logout" path="/logout" methods="GET">
<path locale="en">/logout</path>
<path locale="fr">/deconnexion</path>
</route>
</routes>

.. code-block:: php

// config/routes.php
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;

return function (RoutingConfigurator $routes): void {
$routes->add('app_logout', [
'en' => '/logout',
'fr' => '/deconnexion',
])
->methods(['GET'])
;
};

Then, pass the route name to the ``path`` option:

.. configuration-block::

.. code-block:: yaml

# config/packages/security.yaml
security:
# ...

firewalls:
main:
# ...
logout:
path: app_logout

.. code-block:: xml

<!-- config/packages/security.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<srv:container xmlns="http://symfony.com/schema/dic/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:srv="http://symfony.com/schema/dic/services"
xsi:schemaLocation="http://symfony.com/schema/dic/services
https://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/security
https://symfony.com/schema/dic/security/security-1.0.xsd">

<config>
<!-- ... -->

<firewall name="main">
<logout path="app_logout"/>
</firewall>
</config>
</srv:container>

.. code-block:: php

// config/packages/security.php
use Symfony\Config\SecurityConfig;

return static function (SecurityConfig $security): void {
// ...

$mainFirewall = $security->firewall('main');
// ...
$mainFirewall->logout()
->path('app_logout')
;
};

.. _retrieving-the-user-object:

Fetching the User Object