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 his 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 LoginSuccessHandler class. This class will catch a "logout" event, log the user out and append a GET parameter to a target URL of your choosing. Create the following file

src/Security/LoginSuccessHandler.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 "reason". If found, it will redirect to a target of your choosing and 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