Symfony 4:在自定义控制器中注销用户

I have followed the tutorial to make may application able to logout users simply by calling a route like /logout (Via the Security module as described in the official documentation). It works.

Now I would like to logout the user (still logged via the described in the doc "Remember me" function) in my own controllers (For example before an email validation, in case another session is still opened under another account). But none of my methods works, it makes me crazy. I have tried $session->clear(), $session->invalidate(), $request->getSession->clear(), $request->getSession->Invalidate(), etc. etc. Nothing works.

So my question are, please: How do you do it? How should I handle this case? Is it related to the "remember me" functionality (maybe it's managed in another cookie or something?) ?

Thanks in advance

Your guess might be right, that the issue could be related to the remember me functionality as this will use cookies to store the token, instead of the session, and therefore need a different LogoutHandler.

Symfony provides multiple ways to handle authentication and you will need the correct LogoutHandler(s) depending on your current settings.

Solving your issue is surprisingly hard if you don't just want to redirect the user to the logout path. The "best" way I can think of right now, is simulating a logout-request by building the Request-object manually and then dispatching a GetResponseEvent with it so, that the LogoutListener will be triggered. Dispatching the event might have weird side effects, so you might even want to trigger the listener directly. It could look something like this:

use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Security\Http\Firewall\ListenerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;

class MyController
{
    private $kernel;
    private $logoutListener;

    public function __construct(HttpKernelInterface $kernel, LogoutListenerInterface $logoutListener)
    {
        $this->kernel = $kernel;
        $this->logoutListener = $logoutListener;
    }

    private function customLogout()
    {
        // This needs to be updated whenever the logout path in your security.yaml changes. Probably something you want to improve on.
        $request = Request::create('/logout');

        $event = new GetResponseEvent($this->kernel, $request);

        $this->logoutListener->handle($event);
    }

    public function someAction()
    {
        $this->customLogout();

        // Do whatever you want to do for your request
    }
}

I don't think this is a good solution as interfering with the security system is inherently dangerous. Directly calling the LogoutListener and passing around the kernel are also a bit iffy. To be honest I'm not even 100% sure this will work, but this is the closest to what I could come up with as a possible solution to your problem. You might want to rethink what you are doing and find an alternative approach.