Add User Message After Logging out in Symfony

programming Mar 14, 2023

Synopsis

Here's the dilemma - you want to programmatically log a user out in your Symfony application. After the user has been logged out and redirected, you want to display a custom message. The problem with this situation is, that after logging a user out, all of the session data is deleted. Therefore, it makes it impossible to extract and display session relevant messages. In this article we will discuss how to implement a solution to this problem.

LogoutSuccessHandler

To get started, we will need to create a LogoutSuccessHandler class. This class will catch a logout event, log the user out and append a GET parameter to the target URL of your choosing. Create the following file

src/Security/LogoutSuccessHandler.php 

and add the following code:

<?php
declare(strict_types=1);

namespace App\Security;
 
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\HttpUtils;
use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
 
/**
 * Display a custom message after the user has logged out
 */
class LogoutSuccessHandler implements LogoutSuccessHandlerInterface
{
    protected $httpUtils;
    protected $targetUrl;
 
    /**
     * @param HttpUtils $httpUtils
     */
    public function __construct(HttpUtils $httpUtils)
    {
        $this->httpUtils = $httpUtils;
        $this->targetUrl = '/login';
    }
 
    /**
     * {@inheritdoc}
     */
    public function onLogoutSuccess(Request $request)
    {
    	$reason   = $request->query->get('reason') ?? '';
        $url      = $reason ? $this->targetUrl . '?reason=' . $reason : $this->targetUrl;
        $response = $this->httpUtils->createRedirectResponse($request, $url);
 
        return $response;
    }
}

This class implements the LogoutSuccessHandlerInterface and implements the method "onLogoutSuccess". When triggered, this code will check for the GET parameter which we will call "reason" for this example. If the GET parameters is found, it will redirect the user to a target URL of your choosing. Additionally, it will pass the "reason" parameter along to the URL.

Trigger the Logout

Let's create a controller which will trigger the logout handler. Create the file:

src/Controller/ExampleController.php

and add the following code:

<?php
declare(strict_types=1);

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;

/**
 * Example Controller
 */
class ExampleController extends AbstractController
{
    /**
     * Example method of how to trigger logout with messagel
     *
     * @Route("/logout-with-message", name="logout-with-message")
     */
    public function example(Request $request)
    {
        // log the user out and append reason...
        $logout = $this->generateUrl('logout', ['reason' => 'xyz']);
        return $this->redirect($logout);
    }
}

Update the Template

We specified in the LogoutSuccessHandler class, to redirect to the /login route. To complete the example, we will modify the twig template and output the "reason" message like so:

{% if app.request.get('reason') == "xyz" %}
  <p class="alert">
    This is the message we wanted to pass along.
  </p>
{% endif %}

There you have it. Feel free to leave a comment if this helped you in any way.

Tags