Add User Message After Logging out in Symfony
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.