Download the PHP package trianity/laravel-otp without Composer
On this page you can find all versions of the php package trianity/laravel-otp. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Informations about the package laravel-otp
Laravel OTP
Source code · MIT License
OTP generator and validator for Laravel applications. The package stores OTP records in the database and supports configurable token length, expiry, regeneration limits, and validation attempt limits.
The package was inspired by seshac/otp-generator.
Generated OTP values are returned only from generate(). The database stores a
hash of the token, and a successfully validated OTP is immediately marked as
expired so it cannot be reused.
Requirements for 2.x
- PHP
^8.4(including PHP 8.4 and 8.5) - Laravel 12 or Laravel 13 (
illuminate/support^12.0|^13.0)
Laravel 13 is the primary target. A database connection configured in your Laravel application is required to store OTP records.
Installation
Install the stable 2.x series with Composer:
Laravel automatically discovers the service provider and the Otp facade;
manual registration is not required.
The package automatically loads its migrations. Run your migrations after installation:
Applications upgrading from 1.0.0 must also run this command so the corrective
generated_at migration is applied. Do not overwrite the old migration or use
migrate:fresh; follow UPGRADE-2.0.md.
Publish the configuration and translation files when you want to customize them:
This publishes the following files:
config/otp.phplang/vendor/otp
Basic Usage
On success, generate() returns an object with status, token, message, and code.
On failure, it returns status => false, message, and code; check status
before accessing token.
The plain-text token is available in the response only; it is never stored in
the database.
Successful validation returns an object similar to:
After a successful validation, validating the same OTP again returns a failed response because the stored record is marked as expired.
Get the expiration time for an existing OTP:
The returned object contains an expired_at Carbon instance when the OTP
exists.
If an OTP does not exist, has expired, or has reached its attempt limit,
validate() returns status => false. A successful validation consumes the
OTP.
Validation Rule
Use Trianity\Otp\Rules\OtpRule when the OTP check belongs in a Laravel
validator or FormRequest.
The rule calls Otp::validate(). A successful validation consumes the OTP, so
use it only in the final step of the login or verification flow.
Controller Example
The package does not register application routes. Keep routing, guards, user lookup, session handling, and responses in your app:
Configuration
You can configure the package in config/otp.php:
The default configuration allows five validation attempts and five generated
OTPs per identifier during the cleanup period. The OPT_LENGTH variable name
is retained for compatibility with the package configuration.
Advanced Usage
Configuration values can also be overridden fluently for a call chain:
Fluent overrides apply to the current terminal call only. After generate(),
validate(), or expiredAt(), the generator resets to config/otp.php values.
Available fluent setters map to the package settings:
setValidity(int $minutes)setLength(int $length)setMaximumOtpsAllowed(int $count)setOnlyDigits(bool $onlyDigits)setUseSameToken(bool $useSameToken)setAllowedAttempts(int $count)
Because tokens are stored as hashes, setUseSameToken(true) keeps the existing
stored token valid for the identifier, but it returns token => null on later
calls. If you need to resend the same code, keep the generated token from the
original generate() response in your delivery flow.
Custom OTP clock
Version 2.1 adds the optional Trianity\Otp\Contracts\OtpClock extension point:
By default, LaravelOtpClock reads Laravel's Carbon clock on every call. This
preserves the existing application timezone and Carbon test-time behaviour; it
does not capture a time in its constructor or change global clock state.
An application that needs OTPs to use the real system clock while its global Carbon clock is frozen can provide a native implementation:
Bind it from an application service provider:
The same binding must be loaded in HTTP, queue-worker, and console processes so
all OTP lifecycle decisions use one time source. A long-running clock service
must calculate the current time inside now() rather than storing its
construction time.
Automated tests can bind a mutable fake without changing Carbon globally:
Restore the binding after the test, for example with
$this->app->forgetInstance(OtpClock::class). Changing clocks does not migrate,
rewrite, or delete existing OTP records. Plan how active codes will be
invalidated or allowed to expire before switching between time sources.
Database and cleanup
The package loads its OTP migration automatically. Each identifier has one
stored OTP record; regenerating an OTP updates that record. Expired records and
records older than deleteOldOtps minutes are removed when a new OTP is
generated.
generated_at is application-managed. It changes when generate() creates or
regenerates an OTP, including a useSameToken resend, but not when counters or
other columns change. Generation, regeneration, expiry checks, and cleanup use
the bound OtpClock. With the default binding, Laravel's Carbon test clock
continues to control all these operations. An OTP is valid through its exact
expiry instant and is expired immediately after it.
The package does not register routes, send messages, or implement a login flow. Deliver the returned token through the channel used by your application and keep routing, user lookup, guards, sessions, and responses in your app.
Testing
From a source checkout, install development dependencies and run the checks:
The MariaDB integration suite is opt-in and requires an isolated database:
Changelog
See UPGRADE-2.0.md for the 1.0.0 to 2.0.0 database upgrade.
License
This package is licensed under the MIT License.