Download the PHP package torqie/laravel-passwordless without Composer
On this page you can find all versions of the php package torqie/laravel-passwordless. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download torqie/laravel-passwordless
More information about torqie/laravel-passwordless
Files in torqie/laravel-passwordless
Package laravel-passwordless
Short Description Passwordless authentication for Laravel with magic links and login codes
License MIT
Homepage https://github.com/torqie/laravel-passwordless
Informations about the package laravel-passwordless
laravel-passwordless
Passwordless authentication for Laravel via magic links and login codes (OTP). No passwords, no complexity — just click a link or type a code.
- 🔗 Magic links — a signed, time-limited URL sent by email; click to log in instantly
- 🔢 Login codes — a short numeric/alphanumeric code sent by email; enter it on a verify form
- 🔄 Use one flow, the other, or both at the same time
- 🎛 Fully customisable — swap views, swap action classes, configure everything via
config/passwordless.php
Requirements
| Dependency | Version |
|---|---|
| PHP | 8.3+ |
| Laravel | 12.61.1+ or 13.12.0+ |
Installation
Install via Composer:
Then run the interactive install wizard:
The wizard walks you through every setup step and writes to your .env automatically:
Use --force to overwrite any already-published files when re-running:
Manual installation (optional)
If you prefer to run each step yourself:
Note: publishing migrations gives you two files.
create_passwordless_tableis required.make_password_nullable_on_users_tableonly matters if youruserstable already has apasswordcolumn — it is guarded bySchema::hasColumn, so on a passwordless-first app it is a no-op you can safely delete before migrating.
Setup
1. Add the trait to your User model
2. Configure your user model (if not App\Models\User)
Or via .env:
3. Routes are registered automatically
The package registers all routes under the configured prefix (default: /auth). No additional route registration is needed.
Usage
Using the built-in routes
The package ships with ready-made routes and controllers for both flows. After installation you get these routes out of the box:
| Method | URI | Name | Description |
|---|---|---|---|
GET |
/auth/magic-link |
passwordless.magic-link.request |
Show email form |
POST |
/auth/magic-link |
passwordless.magic-link.send |
Send magic link email |
GET |
/auth/magic-link/{token} |
passwordless.magic-link.authenticate |
Authenticate via clicked link |
GET |
/auth/code |
passwordless.login-code.request |
Show email form |
POST |
/auth/code |
passwordless.login-code.send |
Send login code email |
GET |
/auth/code/verify |
passwordless.login-code.verify |
Show code entry form |
POST |
/auth/code/verify |
passwordless.login-code.authenticate |
Authenticate via submitted code |
Link to either flow from your login page:
Using the fluent API (programmatic)
Use the LaravelPasswordless facade when you need to trigger a magic link or login code from your own code (e.g. inside a controller, job, or listener):
sendMagicLink() and sendLoginCode() both:
- Generate and persist a hashed token
- Send the appropriate notification to the user
- Fire the corresponding event (
MagicLinkSent/LoginCodeSent)
Using the trait helpers directly
The HasPasswordlessAuth trait exposes helpers on your User model:
Configuration
All options live in config/passwordless.php.
type
Which flow(s) to make available. This is informational for your own UI — the package does not restrict routes by this setting.
.env key |
Default |
|---|---|
PASSWORDLESS_TYPE |
both |
ttl
How many minutes a magic link or login code remains valid after being issued.
.env key |
Default |
|---|---|
PASSWORDLESS_TTL |
15 |
code
Settings specific to the login code (OTP) flow.
.env key |
Default |
|---|---|
PASSWORDLESS_CODE_LENGTH |
6 |
PASSWORDLESS_CODE_CHARSET |
0123456789 |
You can make codes alphanumeric:
guard
The authentication guard used when logging the user in.
.env key |
Default |
|---|---|
PASSWORDLESS_GUARD |
web |
user_model
The fully-qualified class name of the authenticatable model to look up by email.
.env key |
Default |
|---|---|
PASSWORDLESS_USER_MODEL |
App\Models\User |
redirects
Where to send the user after a successful login or when a token is invalid/expired.
.env key |
Default |
|---|---|
PASSWORDLESS_REDIRECT_AFTER_LOGIN |
/dashboard |
PASSWORDLESS_REDIRECT_INVALID |
/login |
routes
Prefix and middleware applied to all passwordless routes.
.env key |
Default |
|---|---|
PASSWORDLESS_ROUTE_PREFIX |
auth |
Change the prefix to mount the routes under /login:
views
Override any view by pointing to your own. Set a key to a view string to use it instead of the package default. Leave as null to use the package default.
Example — use your own Blade view for the magic link email:
Your view receives these variables:
| Flow | Variable | Type | Description |
|---|---|---|---|
| Magic link | $url |
string |
The fully-signed magic link URL |
| Magic link | $expiresMins |
int |
TTL in minutes |
| Login code | $code |
string |
The plain-text OTP code |
| Login code | $expiresMins |
int |
TTL in minutes |
Alternatively, publish the built-in views and edit them in your project:
inertia + components
If your app uses Inertia.js, enable this mode so the package renders your Inertia components instead of Blade views.
The quickest way to get started is the install command — it auto-detects your framework and scaffolds ready-to-use component stubs:
Then enable Inertia mode in config/passwordless.php:
Or via .env:
When inertia is true, the controllers call Inertia::render($component, $props) instead of view(). The components keys take precedence over the views keys when Inertia is enabled.
Props passed to each component:
| Component | Prop | Type | Description |
|---|---|---|---|
login_code_verify |
email |
string |
The pending email address from the session |
All other components receive no additional props.
Note: The
inertiajs/inertia-laravelpackage is not a hard dependency of this package — it only needs to be installed in your app if you enable Inertia mode.
Example Vue component for the login code request form:
Example Vue component for the code verify form:
actions
Swap any action class with your own implementation. Your class must implement the corresponding contract from Torqie\LaravelPasswordless\Contracts.
| Config key | Contract | Default |
|---|---|---|
generate_magic_link |
GeneratesMagicLink |
GenerateMagicLinkAction |
authenticate_magic_link |
AuthenticatesViaMagicLink |
AuthenticateViaMagicLinkAction |
generate_login_code |
GeneratesLoginCode |
GenerateLoginCodeAction |
authenticate_login_code |
AuthenticatesViaLoginCode |
AuthenticateViaLoginCodeAction |
resolve_user |
ResolvesUserForSend |
ResolveUserForSendAction |
Customisation
Swapping an action class
-
Create a class that implements the relevant contract:
- Register it in
config/passwordless.php:
The controllers resolve every action through its contract, so the config key is all you need — no service provider bindings.
Passwordless sign-up (customising resolve_user)
ResolveUserForSendAction decides who receives a token when someone submits the send form. It throttles the request, then returns the matching user — or null when the email is unknown, in which case the flow stays silent to avoid leaking which addresses have accounts.
Override it to register unknown emails instead. Call parent::handle() first so the send rate limit still applies:
The new account starts nameless and unverified — clicking the magic link (or entering the code) is the verification. Finish the sign-up on the UserAuthenticatedPasswordlessly event:
Writing a resolver from scratch instead of subclassing? Implement Torqie\LaravelPasswordless\Contracts\ResolvesUserForSend — but bring your own throttling, since that lives in the default action.
Listening to events
The package dispatches three events you can listen to in your EventServiceProvider or using #[Listen] attributes:
| Event | Fired when | Properties |
|---|---|---|
MagicLinkSent |
A magic link is generated and emailed | $authenticatable, $url |
LoginCodeSent |
A login code is generated and emailed | $authenticatable |
UserAuthenticatedPasswordlessly |
A user successfully logs in | $authenticatable, $type (magic_link | login_code) |
Rate limiting
Login code verification is rate-limited at 5 failed attempts per email address using Laravel's RateLimiter. Exceeding the limit returns a ValidationException with a countdown message. The counter is cleared automatically on a successful authentication.
The passwordless.signed middleware
The magic link authenticate route is protected by the passwordless.signed middleware alias, which validates the signed URL signature and expiry. You can apply this middleware to your own routes if needed:
Artisan Commands
passwordless:install
The primary setup wizard. Covers everything in one interactive session: publishing config, migrations, running migrations, choosing your auth flows, scaffolding views or Inertia components, and writing .env keys.
Use --force to overwrite any already-published files when re-running:
passwordless:install-inertia
Standalone command for adding Inertia component stubs to an already-installed app. Reads package.json to auto-detect your framework, or accepts --framework explicitly.
Published files (Vue example):
After running, the command prints the config snippet you need to add to config/passwordless.php to enable Inertia mode.
passwordless:purge
Remove expired and/or used tokens from the database. Run this periodically (e.g. via the scheduler) to keep the passwordless_tokens table clean.
Schedule it in routes/console.php:
Testing
The package ships with a full Pest test suite — 111 tests covering models, actions, controllers, notifications, events, config-driven action swapping, the fluent API, and the purge command.
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
- Terik Hone
- All Contributors
License
The MIT License (MIT). Please see License File for more information.
All versions of laravel-passwordless with dependencies
spatie/laravel-package-tools Version ^1.92
illuminate/contracts Version ^12.61.1||^13.12.0