ajgl/logout-redirector-bundle
Installation:
composer require ajgl/logout-redirector-bundle
Enable the bundle in config/bundles.php:
return [
// ...
Ajgl\LogoutRedirectorBundle\AjglLogoutRedirectorBundle::class => ['all' => true],
];
Configuration:
Add to config/packages/security.yaml:
ajgl_logout_redirector:
redirectors:
- { route: 'homepage', roles: ['ROLE_USER'] }
- { url: 'https://example.com', roles: ['ROLE_GUEST'] }
(Replace routes/URLs with your actual routes.)
First Use Case: After logout, users will automatically redirect to the configured route/URL based on their roles. No additional code needed for basic usage.
Event-Driven:
The bundle listens to Symfony’s LogoutEvent (triggered by security.logout). Customize behavior by extending the LogoutRedirector class or creating a custom event subscriber.
Role-Based Redirects:
Define redirects in security.yaml under ajgl_logout_redirector.redirectors:
redirectors:
- { route: 'dashboard', roles: ['ROLE_ADMIN'] }
- { url: '/login', roles: ['ROLE_USER', 'ROLE_GUEST'] }
(Order matters: first match wins.)
Dynamic Logic: For dynamic redirects (e.g., based on user attributes), create a custom redirector:
// src/Service/CustomLogoutRedirector.php
namespace App\Service;
use Ajgl\LogoutRedirectorBundle\LogoutRedirectorInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\User\UserInterface;
class CustomLogoutRedirector implements LogoutRedirectorInterface
{
public function getRedirectUrl(Request $request, UserInterface $user): ?string
{
if ($user->getRoles()[0] === 'ROLE_PREMIUM') {
return '/premium-thank-you';
}
return null; // Fallback to default config
}
}
Register it in security.yaml:
ajgl_logout_redirector:
redirectors:
- { service: 'App\Service\CustomLogoutRedirector' }
Integration with Forms:
Extend the logout form action to pass dynamic data (e.g., ?redirect=custom_path):
<form action="{{ path('app_logout') }}?redirect=custom_path" method="post">
Fallback Logic:
Use null in redirectors to skip the bundle entirely for specific roles:
redirectors:
- { route: 'homepage', roles: ['ROLE_USER'] }
- { url: null, roles: ['ROLE_EXEMPT'] } # No redirect
Multi-Step Logout:
Combine with Symfony’s logout.success_handler (deprecated in favor of this bundle) or use the LogoutEvent to trigger additional logic:
// src/EventListener/CustomLogoutListener.php
namespace App\EventListener;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\Security\Http\Event\LogoutEvent;
#[AsEventListener(event: LogoutEvent::class)]
class CustomLogoutListener
{
public function onLogout(LogoutEvent $event): void
{
// Custom logic (e.g., analytics, cleanup)
}
}
Deprecated Components:
LogoutSuccessHandler (deprecated since v0.1.0). Use LogoutRedirector or LogoutEvent instead.thecodingmachine/safe is installed (required for URL sanitization).Configuration Overrides:
ajgl_logout_redirector key exists in security.yaml.Symfony Version Mismatch:
composer.json for compatibility.Event Order:
LogoutEvent fires after the bundle processes redirects. Use it for post-logout tasks (e.g., logging), not for redirect logic.Check Redirects:
Enable debug mode (APP_DEBUG=true) to inspect the LogoutEvent payload:
// In a custom listener:
dump($event->getRequest()->getSession()->get('_security_main'));
Validate Routes/URLs:
Use Symfony’s router to test routes:
php bin/console debug:router
Log Redirector Output: Add a temporary listener to debug:
#[AsEventListener(LogoutEvent::class)]
public function debugLogout(LogoutEvent $event): void
{
$this->logger->info('Logout redirect URL:', ['url' => $event->getResponse()?->getTargetUrl()]);
}
Custom Redirectors:
Implement LogoutRedirectorInterface for complex logic:
public function getRedirectUrl(Request $request, UserInterface $user): ?string
{
if ($user->isVerified()) {
return $this->router->generate('verified-dashboard');
}
return '/verify-email';
}
Event Subscribers:
Extend the LogoutEvent for pre/post-logout actions:
#[AsEventListener(LogoutEvent::class)]
public function onLogout(LogoutEvent $event): void
{
$event->setResponse(new RedirectResponse('/custom-logout-page'));
}
Configuration Overrides: Dynamically modify redirects via compiler passes or runtime configuration:
# config/services.yaml
services:
Ajgl\LogoutRedirectorBundle\LogoutRedirector:
arguments:
$redirectors: '%kernel.cache_dir%/custom_redirects.yaml'
php bin/console cache:clear
getRedirectUrl() lightweight to prevent delays during logout. Offload complex logic to pre-logout events.How can I help you explore Laravel packages today?