0

How can i force logout user logged from controle on the new Symfony 6 ? (Version 6.0.1)

I tried $tokenStorage->setToken($token); but setToken() need 2 args:

(public function setToken(string $tokenId, string $token);)

I tried $request->getSession()->invalidate(); but my user is always logged...

I want to logout the user and redirect to another route (à don't want redirect to logout route)

Thank you


I can't use /logout because i'm in a controller, and sometime I have to make sure no user is logged, because i do treatment when I'm comming to this route.

I need this:

When i go to /validate route:

  • if user : logged => logout
  • change somethings to my user, other user and flush some logs to bdd
  • redirect to login page to force login back the user

My service:

<?php

namespace App\Service;

use Symfony\Component\Security\Http\Event\LogoutEvent;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;

class SecurityService
{

    public function forceLogout(
        Request $request,
        EventDispatcherInterface $eventDispatcher,
        TokenStorageInterface $tokenStorage) : void
    {
        $logoutEvent = new LogoutEvent($request, $tokenStorage->getToken());
        $eventDispatcher->dispatch($logoutEvent);
        $tokenStorage->setToken(null);
    }
}

This don't work, my $eventDispatcher->dispacth($logoutEvent) work only before i refresh my page, after i'm logged again !

Ryan M
  • 18,333
  • 31
  • 67
  • 74
  • Normally you can do `$tokenStorage->setToken(null);` not sure if this has changed for Symfony 6. How about `$id = $tokenStorage->getToken()->getId();` then you can `...->setToken($id, null);` – Bossman Apr 27 '22 at 21:30
  • The [TokenStorageInterface](https://github.com/symfony/symfony/blob/6.1/src/Symfony/Component/Security/Core/Authentication/Token/Storage/TokenStorageInterface.php) in Symfony 6 doesn't seem to require 2 arguments. `$tokenStorage->setToken(null)` works fine on my end. – Jeroen van der Laan Apr 27 '22 at 22:21
  • I don't have a 6.0 example handy but basically you need to dispatch a LogoutEvent and then set the token to null. Take a look at the source code for `Symfony\Component\Security\Http\Firewall\LogoutListener::authenticate` and basically copy the relevant code. I know there was talk at one time of encapsulating this functionality into an official Logout service but I don't think that even happened. It is important you send the event even if things seem to work without it. You can easily run into hard to debug issues without it. – Cerad Apr 28 '22 at 13:19

2 Answers2

4

I found soluce :

public function forceLogout() : void
{
    $logoutEvent = new LogoutEvent($this->requestStack->getCurrentRequest(), $this->tokenStorage->getToken());
    $this->eventDispatcher->dispatch($logoutEvent);
    $this->tokenStorage->setToken(null);
    $response = new Response();
    $response->headers->clearCookie('REMEMBERME');
    $response->send();
}
  • This aided me in figuring out what to do. But my company is only using symfony 4.4 so logoutEvent class does not exist. What I did is using the token interface set to null and also invalidate the session. – Gregory Neely Aug 06 '23 at 14:55
1

just redirect to the logout route:

return $this->redirect($this->generateUrl('YourLogoutRouteName'));

Rufinus
  • 29,200
  • 6
  • 68
  • 84