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

Laravel Otp Laravel Package

mkd/laravel-otp

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require mkd/laravel-otp
    

    Publish the config file (if needed):

    php artisan vendor:publish --provider="MKD\LaravelOTP\LaravelOTPServiceProvider"
    
  2. First Use Case: Generate a TOTP secret and verify an OTP in a controller or command:

    use MKD\LaravelOTP\LaravelOTP;
    
    $secret = LaravelOTP::generateSecret(); // Auto-generates a Base32 secret
    $otpService = LaravelOTP::make($secret);
    
    // Generate OTP (6 digits, default 30s window)
    $otp = $otpService->now();
    
  3. Where to Look First:

    • Config: config/laravel-otp.php (if published) for customization (e.g., OTP length, time step).
    • Service Provider: LaravelOTPServiceProvider for binding extensions or overrides.
    • QR Code Helper: LaravelOTP::generateQRCode() for TOTP setup in authenticator apps.

Implementation Patterns

Core Workflows

TOTP (Time-Based) Flow

  1. Setup:

    $secret = LaravelOTP::generateSecret();
    $qrCodeUrl = LaravelOTP::generateQRCode('user@example.com', $secret);
    
    • Store $secret in the user model (e.g., user_otp_secret).
    • Display $qrCodeUrl in a view for authenticator apps (Google Authenticator, Authy).
  2. Verification:

    $otpService = LaravelOTP::make($user->otp_secret);
    $isValid = $otpService->verifyTOTP($userInputOTP, [
        'allowedDeviation' => 1, // Allow ±1 time step (e.g., 30s window)
    ]);
    

HOTP (HMAC-Based) Flow

  1. Generate and Verify:
    $hotpService = LaravelOTP::make($secret, 'hotp');
    $counter = 0; // Track counter (e.g., per login attempt)
    $otp = $hotpService->generateHOTP($counter);
    $isValid = $hotpService->verifyHOTP($userInputOTP, $counter);
    

Integration with Laravel Auth

  • Middleware:
    use MKD\LaravelOTP\Middleware\VerifyOTP;
    
    Route::middleware([VerifyOTP::class])->group(function () {
        // Routes requiring OTP
    });
    
  • Custom Guard: Extend LaravelOTP logic in a custom guard or use it alongside MustVerifyOTP interface.

User Model Integration

// User.php
use MKD\LaravelOTP\Traits\HasOTP;

class User extends Authenticatable
{
    use HasOTP;

    protected $otpSecret;
    protected $otpAlgorithm = 'totp'; // or 'hotp'
}

Advanced Patterns

Dynamic Secrets

  • Store secrets in a database and fetch them dynamically:
    $secret = User::find($id)->otp_secret;
    $otpService = LaravelOTP::make($secret);
    

Rate Limiting

Combine with Laravel’s rate limiting to prevent brute-force attacks:

Route::middleware(['throttle:5,1'])->group(function () {
    Route::post('/verify-otp', [OTPController::class, 'verify']);
});

Fallback Mechanisms

  • Allow email/SMS fallback if OTP verification fails:
    if (!$otpService->verifyTOTP($otp)) {
        $user->sendFallbackVerification();
    }
    

Testing

Use the LaravelOTP facade in tests:

public function test_otp_verification()
{
    $secret = LaravelOTP::generateSecret();
    $otpService = LaravelOTP::make($secret);
    $otp = $otpService->now();

    $this->assertTrue($otpService->verifyTOTP($otp));
}

Gotchas and Tips

Pitfalls

  1. Secret Storage:

    • Never hardcode secrets in config or environment files. Always store them in the database or encrypted storage.
    • Base32 Encoding: Ensure secrets are Base32 encoded (the package handles this, but manual inputs must comply).
  2. Time Synchronization (TOTP):

    • TOTP relies on server time. Use Carbon or DateTime for consistency:
      $otpService->setTimeSource(function () {
          return Carbon::now()->getTimestamp();
      });
      
    • Clock Drift: Allow allowedDeviation (e.g., 1) to account for minor time differences.
  3. HOTP Counters:

    • Counter Management: HOTP requires a monotonically increasing counter. Reset or manage it carefully (e.g., increment per use).
    • Replay Attacks: Store the last used counter to prevent replay attacks.
  4. QR Code Generation:

    • Isset URL: Ensure the issuer parameter in generateQRCode() is URL-encoded:
      $qrCodeUrl = LaravelOTP::generateQRCode(
          urlencode('MyApp'),
          $secret
      );
      
  5. Algorithm Confusion:

    • TOTP vs. HOTP: TOTP is time-based (good for authenticator apps), HOTP is counter-based (good for hardware tokens or sequential logins).

Debugging Tips

  1. OTP Generation:

    • Use LaravelOTP::make($secret)->now() to debug expected OTPs.
    • For TOTP, check the current time step:
      $timeStep = $otpService->getCurrentTimeStep();
      
  2. Verification Issues:

    • Allowed Deviation: Increase allowedDeviation if OTPs fail due to time sync (e.g., 3 for ±90s).
    • Secret Mismatch: Verify the secret matches exactly (case-sensitive, no extra spaces).
  3. Logging:

    • Log OTP attempts for debugging:
      \Log::debug('OTP Verification', [
          'input' => $userInputOTP,
          'expected' => $otpService->now(),
          'valid' => $otpService->verifyTOTP($userInputOTP),
      ]);
      

Extension Points

  1. Custom Algorithms: Extend the MKD\LaravelOTP\Contracts\OTPGenerator interface to support custom algorithms.

  2. Event Listeners: Listen for OTP events (e.g., otp.verified):

    LaravelOTP::addListener('otp.verified', function ($user, $otp) {
        // Trigger post-verification logic
    });
    
  3. Configuration Overrides: Override defaults in config/laravel-otp.php:

    'otp' => [
        'length' => 8, // Default: 6
        'algorithm' => 'sha1', // Default: 'sha256'
        'time_step' => 30, // Seconds for TOTP
    ],
    
  4. Service Binding: Bind custom implementations in the service provider:

    $this->app->bind('otp', function () {
        return new CustomOTPService();
    });
    

Performance

  • Caching: Cache OTP secrets if they rarely change (e.g., in Redis).
  • Batch Verification: For bulk checks (e.g., admin tools), pre-generate OTPs and verify offline.
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.
craftcms/url-validator
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony