Spatie Laravel One-Time Passwords

repository·main·Indexed 41 days ago

https://github.com/spatie/laravel-one-time-passwords

A Laravel package for securely creating and consuming one-time passwords (OTP). It features built-in support for mail notifications, Livewire components, and Flux UI enhancements. The package implements security measures including short expiration (2 minutes by default), context validation of IP and User Agent, and rate limiting to prevent brute-force attacks.

Tokens
10.5K
Snippets
39
Records
54
Agent score
51%

What's inside laravel-one-time-passwords

  1. Overview of one-time-passwords package

    main

    The spatie/laravel-one-time-passwords package allows you to securely create and consume one-time passwords (OTPs) within a Laravel application. It is designed to facilitate OTP-based login flows and includes a built-in Livewire component for quick UI integration.

    To ensure security, the package implements the following defaults:

    • Short Expiration: OTPs expire quickly (2 minutes by default).
    • Context Validation: OTPs can only be consumed if the user agent and IP address match the ones used during generation.
    • Rate Limiting: Login attempts are time-boxed to prevent brute-force attacks.
  2. How one-time passwords are secured

    main

    The package implements several security measures by default:

    • Short Expiration: OTPs expire quickly (2 minutes by default).
    • Context Validation: OTP consumption is restricted to the same IP address and User Agent that was used when the OTP was generated.

    These behaviors are implemented via action classes that can be customized if you need to modify the security logic.

  3. Security features of one-time passwords

    main

    The laravel-one-time-passwords package implements several security measures by default to mitigate the risk of guessable passwords:

    • Expiration: One-time passwords (OTPs) are valid for 2 minutes by default.
    • Origin Validation: OTPs must be used on the same origin that generated them.
    • Single Active OTP: Only one one-time password can be valid for a specific user at any given time.
    • Automatic Invalidation: An OTP is immediately invalidated after it has been successfully used.
  4. Customize origin enforcement with a custom OriginEnforcer

    main

    If the default IP and User Agent check is insufficient, you can implement your own origin enforcement logic by creating a class that implements the Spatie\OneTimePasswords\Support\OriginInspector\OriginEnforcer interface.

    Your implementation must define two methods:

    1. gatherProperties(Request $request): Returns an array<string, string|int> of properties extracted from the current request that should be stored with the one-time password.
    2. verifyProperties(OneTimePassword $oneTimePassword, Request $request): Compares the properties stored in the OneTimePassword model against the current request and returns true if they match, or false otherwise.

    After implementing your class, register it in config/one-time-passwords.php using the origin_enforcer key.

    use Illuminate\\Http\\Request;
    use Spatie\\OneTimePasswords\\Models\\OneTimePassword;
    
    interface OriginEnforcer
    {
        /** @return array<string, string|int> */
        public function gatherProperties(Request $request): array;
    
        public function verifyProperties(OneTimePassword $oneTimePassword, Request $request): bool;
    }
  5. Customize package actions by overriding action classes

    main

    The core functionality of the package is implemented via action classes. You can override default behavior by creating your own action classes that extend the package's base actions and then registering them in the config/one-time-passwords.php configuration file.

    To customize an action (for example, adding logic after a password is created):

    1. Create a new class that extends the original action class (e.g., CreateOneTimePasswordAction).
    2. Override the execute() method.
    3. Call parent::execute() within your method to ensure the core logic runs, then add your custom logic.
    4. Ensure you return the result of the execution.
    5. Register your new class in the actions array of config/one-time-passwords.php using the corresponding action key.
    namespace App\Actions;
    
    use Spatie\OneTimePasswords\Actions\CreateOneTimePasswordAction;
    
    class CustomCreateOneTimePasswordAction extends CreateOneTimePasswordAction
    {
        public function execute(
            Authenticatable $user,
            ?int $expiresInMinutes = null,
            ?Request $request = null
        ): OneTimePassword {
            // Call the parent method to store the one-time password
            $oneTimePassword = parent::execute($user, $expiresInMinutes, $request);
    
            // Add your custom logic here
            
            // Don't forget to return the one-time password
            return $oneTimePassword;
        }
    }