4

The default Symfony behavior is to redirect to '/' after logout. I don't require any redirects from Symfony as it's an api app.

Like how during login when Symfony takes control to do authentication, but then still runs the login controller to perform further actions. This would be ideal for logout in this case also.

security.yaml

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            lazy: true
            provider: app_user_provider

            json_login:
                check_path: app_login
                username_path: email
                password_path: password

            logout:
                path: app_logout

src/Controller/SecurityController.php from Symfony docs

    /**
     * @Route("/logout", name="app_logout", methods={"GET"})
     */
    public function logout(): void
    {
        // controller can be blank: it will never be called!
        throw new \Exception('Don\'t forget to activate logout in security.yaml');
    }
Bradmage
  • 1,233
  • 1
  • 15
  • 41

1 Answers1

3

You can write a custom logout handler. Actually, there is a new approach for this, introduced in symfony 5.1. Basically, now you can register an event listener either globally or for some specific firewall, and perform any actions after the person has logged out.

Returning to your problem (from the blog post below):

The Symfony\Component\Security\Http\Event\LogoutEvent object received by the listener contains useful methods such as getToken() (to get the security token of the session), getRequest() and setResponse().

The later will help you. It means you can return anything you want instead of default RedirectResponse by setting new response object to the event.

services.yaml:

services:
    App\EventListener\CustomLogoutListener:
        tags:
            - name: 'kernel.event_listener'
              event: 'Symfony\Component\Security\Http\Event\LogoutEvent'
              dispatcher: security.event_dispatcher.main
              method: onLogout

And your listener:

namespace App\EventListener;

use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Security\Http\Event\LogoutEvent;

class CustomLogoutListener
{
    public function onLogout(LogoutEvent $logoutEvent): void
    {
        $logoutEvent->setResponse(new JsonResponse([]));
    }
}

Read more: Simpler logout customization

ozahorulia
  • 9,798
  • 8
  • 48
  • 72
  • Thanks for a complete answer, it looks like it would work, I'll play with it over the next few days. I'm guessing this will be to answer. I was really hoping there was a built in solution like `target: null` to cancel the redirect. – Bradmage Dec 18 '21 at 05:41
  • @Bradmage it's rather impossible, since you need at least some kind of a response. So behavior of such `target: null` will be undetermined. – ozahorulia Dec 18 '21 at 05:43
  • I think there was a miscommunication, my intention with `target: null` was to force it to use the `app_logout` method to handle the response. Your solution done exactly what I was after, just the long way to do the same job. – Bradmage Dec 19 '21 at 05:16
  • App\EventListener\CutomLogoutListener: has a typo but I can't edit one character. – Bradmage Dec 19 '21 at 05:17