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

One Time Access Bundle Laravel Package

berny/one-time-access-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require xphere/one-time-access-bundle
    

    Register the bundle in config/bundles.php (Symfony 4+) or AppKernel.php (Symfony 2/3):

    // config/bundles.php
    return [
        // ...
        xPheRe\OneTimeAccessBundle\xPheReOneTimeAccessBundle::class => ['all' => true],
    ];
    
  2. Configure Firewall: Add the one_time_access key to your firewall in config/packages/security.yaml (Symfony 4+) or app/config/security.yml (Symfony 2/3):

    security:
        firewalls:
            ota:
                one_time_access:
                    route: app_ota_auth  # Must match your route name
                    # Optional: Customize token TTL (default: 3600 seconds)
                    ttl: 3600
    
  3. Create a Route: Define a route for the one-time access URL (e.g., routes/ota.yaml):

    app_ota_auth:
        path: /auth/{token}
        controller: xPheRe\OneTimeAccessBundle\Controller\OneTimeAccessController::authenticateAction
        requirements:
            token: '[a-zA-Z0-9_-]{32}'
    
  4. Generate a Token: Use the OneTimeAccessGenerator service to create a token for a user:

    use xPheRe\OneTimeAccessBundle\Generator\OneTimeAccessGenerator;
    
    $generator = $this->container->get('xphere_one_time_access.generator');
    $token = $generator->generateToken($user);
    

    Share this token via email/SMS (e.g., in a "Forgot Password" flow).


First Use Case: Passwordless Login

  1. Trigger Token Generation: In your User controller, generate a token when a user requests access:

    public function requestAccess(User $user, OneTimeAccessGenerator $generator)
    {
        $token = $generator->generateToken($user);
        // Send $token via email/SMS to the user.
        return new Response('Check your email for a one-time login link.');
    }
    
  2. User Clicks Link: The user visits /auth/{token}. The firewall validates the token, logs them in, and redirects to the dashboard.


Implementation Patterns

Workflows

1. Token-Based Authentication

  • Generate: Create tokens for users (e.g., after registration or password reset).
    $token = $generator->generateToken($user, ['ip' => $request->getClientIp()]);
    
    Optional: Bind tokens to metadata (e.g., IP, user agent) for security.
  • Validate: The firewall automatically validates tokens on route access. Customize behavior via events:
    # config/packages/security.yaml
    firewalls:
        ota:
            one_time_access:
                route: app_ota_auth
                events:
                    on_auth_success: app.ota.on_auth_success
                    on_auth_failure: app.ota.on_auth_failure
    

2. Multi-Firewall Support

Use separate firewalls for different use cases (e.g., admin vs. user OTA):

firewalls:
    user_ota:
        one_time_access:
            route: app_user_ota_auth
            ttl: 1800  # 30 minutes
    admin_ota:
        one_time_access:
            route: app_admin_ota_auth
            ttl: 3600
            # Custom provider
            provider: admin_user_provider

3. Token Expiration and Revocation

  • TTL: Set a short lifespan (e.g., 30 minutes) for tokens.
  • Revocation: Manually revoke tokens via the OneTimeAccessManager:
    $manager = $this->container->get('xphere_one_time_access.manager');
    $manager->revokeToken($token);
    

Integration Tips

Laravel-Specific Adaptations

  1. Service Container: Bind the Symfony services to Laravel’s container in AppServiceProvider:

    public function register()
    {
        $this->app->bind('xphere_one_time_access.generator', function ($app) {
            return new \xPheRe\OneTimeAccessBundle\Generator\OneTimeAccessGenerator(
                $app['xphere_one_time_access.manager'],
                $app['xphere_one_time_access.token_storage']
            );
        });
    }
    
  2. Middleware: Replace Symfony’s firewall with Laravel middleware. Create a custom middleware to handle OTA:

    namespace App\Http\Middleware;
    
    use Closure;
    use xPheRe\OneTimeAccessBundle\Generator\OneTimeAccessGenerator;
    
    class OneTimeAccessMiddleware
    {
        protected $generator;
    
        public function __construct(OneTimeAccessGenerator $generator)
        {
            $this->generator = $generator;
        }
    
        public function handle($request, Closure $next)
        {
            $token = $request->route('token');
            // Validate token and set user...
            return $next($request);
        }
    }
    

    Register it in app/Http/Kernel.php:

    protected $routeMiddleware = [
        'ota' => \App\Http\Middleware\OneTimeAccessMiddleware::class,
    ];
    
  3. Routing: Use Laravel’s routing syntax:

    Route::get('/auth/{token}', [OneTimeAccessController::class, 'authenticateAction'])
        ->middleware('ota')
        ->name('app.ota_auth');
    

Customizing Token Generation

Extend the default generator to add metadata (e.g., user agent, IP):

namespace App\Services;

use xPheRe\OneTimeAccessBundle\Generator\OneTimeAccessGenerator as BaseGenerator;

class CustomOneTimeAccessGenerator extends BaseGenerator
{
    public function generateToken($user, array $metadata = [])
    {
        $metadata['user_agent'] = request()->userAgent();
        $metadata['ip'] = request()->ip();
        return parent::generateToken($user, $metadata);
    }
}

Bind it in AppServiceProvider:

$this->app->bind('xphere_one_time_access.generator', function ($app) {
    return new CustomOneTimeAccessGenerator(
        $app['xphere_one_time_access.manager'],
        $app['xphere_one_time_access.token_storage']
    );
});

Gotchas and Tips

Pitfalls

  1. Token Storage:

    • The bundle uses Symfony’s security.token_storage by default. In Laravel, ensure this is properly mocked or replaced.
    • Fix: Use Laravel’s Auth facade to store the user after validation:
      Auth::login($user);
      
  2. Route Requirements:

    • The route must match the token regex ([a-zA-Z0-9_-]{32}). Customize this in your route:
      app_ota_auth:
          path: /auth/{token}
          requirements:
              token: '[a-zA-Z0-9_-]{43}'  # Adjust length as needed
      
  3. Firewall Configuration:

    • The one_time_access key must include a route. Omitting this will cause a ConfigurationException.
    • Symptom: No route defined for one-time access firewall.
    • Fix: Always specify route: your_route_name.
  4. Token Revocation:

    • Tokens are not automatically revoked after use. Implement logic to revoke them post-authentication:
      public function authenticateAction($token)
      {
          // Validate token...
          $manager->revokeToken($token); // Revoke after use
          Auth::login($user);
          return redirect('/dashboard');
      }
      
  5. Symfony-Specific Assumptions:

    • The bundle assumes Symfony’s UserInterface. For Laravel, ensure your User model implements Symfony\Component\Security\Core\User\UserInterface:
      use Symfony\Component\Security\Core\User\UserInterface;
      
      class User implements UserInterface
      {
          // ...
      }
      

Debugging

  1. Token Validation Failures:

    • Check if the token exists in storage:
      $manager = $this->container->get('xphere_one_time_access.manager');
      $tokenData = $manager->findToken($token);
      
    • Common Causes:
      • Token expired (TTL passed).
      • Token was revoked manually.
      • Incorrect token format (e.g., URL-encoded characters).
  2. Firewall Not Triggering:

    • Verify the firewall is applied to the correct route and that the route matches the route key in the firewall config.
    • Debug: Add a dump() in a custom event listener for on_auth_attempt.
  3. User Not Logged In:

    • Ensure the TokenStorage is updated after validation. In Laravel, use Auth::login($user) explicitly.

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.
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
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai