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 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.