Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Logout Redirector Bundle Laravel Package

ajgl/logout-redirector-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require ajgl/logout-redirector-bundle
    

    Enable the bundle in config/bundles.php:

    return [
        // ...
        Ajgl\LogoutRedirectorBundle\AjglLogoutRedirectorBundle::class => ['all' => true],
    ];
    
  2. 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.)

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


Implementation Patterns

Core Workflow

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

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

  3. 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' }
    
  4. 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">
    

Advanced Patterns

  • 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)
        }
    }
    

Gotchas and Tips

Pitfalls

  1. Deprecated Components:

    • Avoid using LogoutSuccessHandler (deprecated since v0.1.0). Use LogoutRedirector or LogoutEvent instead.
    • Ensure thecodingmachine/safe is installed (required for URL sanitization).
  2. Configuration Overrides:

    • If redirects don’t work, verify:
      • The ajgl_logout_redirector key exists in security.yaml.
      • Roles match exactly (case-sensitive).
      • No typos in route names/URLs.
  3. Symfony Version Mismatch:

    • The bundle supports Symfony 5.4+ and 6.2+ (PHP 8.0+). Check composer.json for compatibility.
  4. Event Order:

    • The LogoutEvent fires after the bundle processes redirects. Use it for post-logout tasks (e.g., logging), not for redirect logic.

Debugging Tips

  • 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()]);
    }
    

Extension Points

  1. 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';
    }
    
  2. 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'));
    }
    
  3. 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'
    

Performance Notes

  • Caching: The bundle caches redirect configurations. Clear cache after changes:
    php bin/console cache:clear
    
  • Avoid Heavy Logic: Keep getRedirectUrl() lightweight to prevent delays during logout. Offload complex logic to pre-logout events.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle