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

Persona Bundle Laravel Package

ahs/persona-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install via Composer

    composer require ahs/persona-bundle
    
  2. Enable the Bundle Add to app/AppKernel.php:

    new AHS\PersonaBundle\AHSPersonaBundle(),
    
  3. Configure Security Update app/config/security.yml:

    firewalls:
        persona_secured:
            pattern:    ^/
            persona:    true
            logout:     true
            anonymous:  true
    
  4. Set Persona URLs Configure in app/config/config.yml:

    ahs_persona:
        verifier_url: "https://verifier.login.persona.org/verify"
        audience_url: "https://your-app.example.com"
    
  5. First Use Case Deploy and visit your app. The bundle provides a /login route (default) for Persona authentication. Test by clicking the login link—it redirects to Mozilla Persona for verification.


Implementation Patterns

Workflow Integration

  1. Authentication Flow

    • User clicks a login link (e.g., /login).
    • Bundle redirects to Persona’s verification endpoint (verifier_url).
    • After verification, Persona redirects back to your app with an assertion query param.
    • Bundle validates the assertion and logs the user in (using an in-memory provider by default).
  2. Customizing the Login Route Override the default route in routing.yml:

    ahs_persona_login:
        path: /auth/persona
        defaults: { _controller: AHSPersonaBundle:Security:login }
    
  3. User Identity Handling The bundle uses the email from the Persona assertion as the Symfony username. Extend the AHSPersonaUserProvider to map emails to custom user entities:

    // src/AHS/PersonaBundle/DependencyInjection/Compiler/UserProviderPass.php
    class UserProviderPass extends CompilerPass {
        public function process(ContainerBuilder $container) {
            $definition = $container->findDefinition('ahs_persona.user_provider');
            $definition->setClass('AppBundle\Security\CustomPersonaUserProvider');
        }
    }
    
  4. Twig Integration (Manual) Since the bundle lacks built-in Twig helpers, create a custom extension:

    {% if app.user %}
        Logged in as {{ app.user.email }}
        <a href="{{ path('logout') }}">Logout</a>
    {% else %}
        <a href="{{ path('ahs_persona_login') }}">Login with Persona</a>
    {% endif %}
    
  5. FOSUserBundle Compatibility (Partial) While the bundle doesn’t natively support FOSUserBundle, manually register a UserProvider:

    # app/config/security.yml
    providers:
        fos_userbundle:
            id: fos_user.user_provider.username_email
    firewalls:
        main:
            pattern: ^/
            form_login:
                provider: fos_userbundle
                login_path: ahs_persona_login
                check_path: ahs_persona_check
    

Gotchas and Tips

Pitfalls

  1. Deprecated Symfony Version The bundle requires Symfony 2.1–2.3-dev. Use with Symfony 2.7/2.8 may break due to API changes. Test thoroughly or fork the bundle.

  2. In-Memory Provider Limitation The default InMemoryUserProvider stores users in memory. For production, implement a custom provider (e.g., Doctrine-based) to persist sessions:

    // src/AppBundle/Security/CustomPersonaUserProvider.php
    class CustomPersonaUserProvider extends AHSPersonaUserProvider {
        public function loadUserByUsername($email) {
            return $this->entityManager->getRepository('AppBundle:User')
                ->findOneBy(['email' => $email]);
        }
    }
    
  3. CSRF Token Issues The /login route may fail if CSRF protection is enabled. Disable it for the Persona firewall:

    firewalls:
        persona_secured:
            pattern:    ^/
            persona:    true
            logout:     true
            anonymous:  true
            context:    main  # Ensure this matches your security context
    
  4. Audience URL Mismatch The audience_url must match the exact domain where users are redirected after login. Use HTTPS and avoid local dev URLs (e.g., http://localhost).

  5. No Built-in Logout Button The bundle provides a logout route (/logout) but no Twig helper. Create a custom route or use:

    <a href="{{ path('logout', {'_route_params': {'_locale': app.request.locale}}) }}">Logout</a>
    

Debugging Tips

  1. Enable Debugging Add to config.yml to log assertions:

    ahs_persona:
        debug: true
    
  2. Verify Assertions Manually Check the assertion query param in the redirect URL. Use Mozilla’s Persona Verifier to validate it offline.

  3. Check Browser Console Persona errors (e.g., invalid assertions) may appear in the browser console. Inspect the redirect flow:

    your-app.com → persona.org → your-app.com?assertion=...
    
  4. Clear Cache After Config Changes Run:

    php app/console cache:clear
    

Extension Points

  1. Custom User Provider Override the AHSPersonaUserProvider to integrate with your user model:

    // src/AppBundle/Security/CustomPersonaUserProvider.php
    class CustomPersonaUserProvider extends AHSPersonaUserProvider {
        public function loadUserByUsername($email) {
            // Fetch user from DB or create if missing
        }
    }
    

    Register it in services.yml:

    services:
        app.persona.user_provider:
            class: AppBundle\Security\CustomPersonaUserProvider
            arguments: [@doctrine.orm.entity_manager]
            tags:
                - { name: security.user_provider, id: persona }
    
  2. Post-Login Redirects Extend the AHSPersonaListener to redirect users after login:

    // src/AppBundle/EventListener/PersonaLoginListener.php
    class PersonaLoginListener {
        public function onPersonaSuccess(GetResponseUserEvent $event) {
            $request = $event->getRequest();
            $session = $request->getSession();
            $targetPath = $session->get('_security.main.target_path');
            if (!$targetPath) {
                $event->setResponse(new RedirectResponse('/dashboard'));
            }
        }
    }
    

    Register the listener in services.yml:

    services:
        app.persona.login_listener:
            class: AppBundle\EventListener\PersonaLoginListener
            tags:
                - { name: kernel.event_listener, event: security.interactive_login, method: onPersonaSuccess }
    
  3. Add Persona to Existing Firewall Combine with form/login firewalls:

    firewalls:
        main:
            pattern: ^/
            form_login:
                provider: fos_userbundle
            persona:
                verifier_url: "https://verifier.login.persona.org/verify"
                audience_url: "https://your-app.example.com"
    
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity