Weave 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 One Time Passwords

Laravel One Time Passwords Laravel Package

spatie/laravel-one-time-passwords

Spatie's Laravel One-Time Passwords package lets you securely create and consume OTPs, defaulting to six-digit codes sent by mail. Extend notifications to SMS or other channels, use the included Livewire login component, and optionally enhance input with Flux.

View on GitHub
Deep Wiki
Context7

This package lets you securely create and consume one-time passwords (OTP) in Laravel applications. By default, an OTP is a six-digit code delivered through a mail notification that can be extended to other channels such as SMS. A ready-made Livewire component provides a complete passwordless login flow out of the box, and it automatically upgrades to the Flux OTP input when Flux is installed.

  • Secure generation and consumption of one-time codes
  • Mail delivery via extensible notifications (e.g. SMS)
  • Ready-to-use Livewire login form
  • Automatic Flux OTP input support
  • Simple API for building a custom UI
Frequently asked questions about Laravel One Time Passwords
How do I install and set up spatie/laravel-one-time-passwords in a Laravel app?
Install it with Composer using composer require spatie/laravel-one-time-passwords, then publish and run the migration that creates the one-time password table and publish the config file. Add the package trait to your authenticatable model so it gains the sendOneTimePassword() and attemptLoginUsingOneTimePassword() methods. That is the entire setup surface: a migration, a config file, a mail notification and one trait on your user model. No external service, sidecar or new datastore is required, so it drops into a standard Laravel app cleanly.
Does the package include a ready-made Livewire login component?
Yes. It ships with an opinionated Livewire component that provides the email entry screen and the code entry screen for passwordless login. If Flux is installed, the component automatically switches to the Flux OTP input component instead of a standard text input. You can use the component as-is for a near-zero-frontend pilot, or skip it entirely and build your own flow on the underlying methods.
How do I send one-time passwords via SMS instead of email?
By default an OTP is a six-digit code delivered through a mail notification, but that notification is built to be extended so it can go out over SMS or any other channel. Swap the notification or add a channel for your SMS provider while keeping the same generation, expiry and consumption logic. Everything else in the flow, including single-use enforcement and the attemptLoginUsingOneTimePassword() call, stays identical across channels.
How long is an OTP valid and can I change the expiry time?
The default lifetime is two minutes, and it is configurable in the package's config file. Because the window is short, your transactional mail latency matters: if email takes longer than that to arrive, codes expire before users can type them. Raising the expiry buys tolerance for slow delivery but weakens the security story, so validate your provider's p99 latency before committing to the default.
Can I build a custom OTP login flow without the Livewire component?
Yes. The package exposes simple methods on your user model, such as sendOneTimePassword() and attemptLoginUsingOneTimePassword(), plus a result enum so you can react to success and failure cases. That lets you build a fully branded flow in your own controller, Blade view, Inertia page or API endpoint. You keep the same security behaviour without adopting the bundled Livewire UI.
Which Laravel and Livewire versions does spatie/laravel-one-time-passwords support?
The package is Laravel-native and has tracked current framework releases, with Laravel 13 and Livewire 4 support added inside the 1.x line. Livewire is optional: install it only if you want the bundled login component. Always check the Composer constraints on Packagist against your app's PHP and Laravel versions before upgrading, since minor releases can move the requirement.
Are OTPs hashed in the database, and do I need to clean up expired codes?
Codes are stored in a table created by the package's published migration, but hashing at rest and automatic purging are not clearly documented, so verify both in the source before going live. If expired rows are not purged automatically, schedule a cleanup job or prune command for the table. This is a must-verify item for a security review, together with whether user enumeration is possible when a code is requested.
How does the package protect against brute force and replay of one-time passwords?
Each code is short-lived and single-use, and the package applies rate limiting with translated error messages when attempts are exceeded. It also binds a code to the originating IP and user agent and enforces same-origin requests, with the enforce_same_origin config fixed to actually be respected in 1.1.0. Version 1.1.1 changed Timebox to return early on successful consumption, which shows active refinement of replay handling, but you should still verify atomic single-use consumption on your database engine.
Why do some users get a different origin or validation error when logging in with an OTP?
The package pins each code to the requesting IP address and user agent, so legitimate users on mobile networks, VPNs, corporate proxies or after a browser auto-update can fail closed with a validation error. Note that the translation key was renamed from request_did_not_match to different_origin within 1.x, which can break assertions in your tests and change user-facing messages. Treat identity binding as a product decision: keep it for tighter security, or relax it if support contacts become the bigger cost.
Is spatie/laravel-one-time-passwords production-ready?
It is a narrow, well-documented Spatie package with CI, PHPStan, a changelog and regular releases, but adoption is still modest at roughly 183 GitHub stars and no declared dependents, so treat 1.x as credible but young. Because it sits directly on the login path, a defect is an account-takeover class incident, which justifies a threat model, focused code review and penetration test rather than a normal pull request review. Keep an eye on minor releases too, since behavioural and translation-string changes have shipped inside 1.x.
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.
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo
bernskioldmedia/laravel-harvest
bernskiold/laravel-data-scrubber
bernskiold/laravel-currency-converter
bernskiold/laravel-campaign-monitor
bernskioldmedia/laravel-autotranslate
siberfx/telegram-bot
roy-sandip/laravel-view-extended
gregsphotography/site-builder-core
roy-sandip/laravel-view
anodyne/blade-fluentui-icons
webx-ui/module-catalog-collections