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 Magic Auth Laravel Package

soved/laravel-magic-auth

Laravel Magic Auth adds passwordless magic link login to your Laravel app. Users sign in via a secure emailed link instead of a password, with configurable token lifetimes, single-use URLs, and simple integration into existing auth guards.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install and see what you got. composer require soved/laravel-magic-auth, then immediately open vendor/soved/laravel-magic-auth/ and read composer.json, the service provider, and src/. This package has no dependents and last shipped in 2020, so the source is your documentation — the README is thin and the API surface is small.
  2. Publish config (if exposed). php artisan vendor:publish --tag=magic-auth (or inspect boot() in the service provider for the real tag) to get config/magic-auth.php. Look for the expiry window, the user model/table, and the post-login redirect.
  3. Wire the trait onto your model. The package almost certainly ships a trait (something like HasMagicAuth) that you add to App\Models\User. It provides the URL generator and the notification trigger. Add it, then run php artisan config:clear before testing.
  4. First use case: a passwordless login form. Build one controller with two actions — show (email form) and send (validate email, trigger the link). That's the whole feature; don't try to also replace registration on day one.
  5. Verify mail in local. Use log or Mailhog as your mailer so you can click the link out of storage/logs/laravel.log. Test with php artisan route:list to see which routes the provider registered — you need to know the exact URI and middleware before you can protect or rate-limit it.

Implementation Patterns

Standard email → link → session flow. A POST /magic-login action validates the email, looks up the user, and calls the trait's send method. The generated link hits the package's handler route, which authenticates and redirects. Keep your own controller thin and let the package own the callback route.

Never reveal whether the account exists. The send action should always return the same 200/"check your inbox" response, whether the user was found or not. Only call the notification when the user exists, and swallow the branch in your response. This is the single most common security regression in magic-link implementations.

Coexist with passwords rather than replacing them. Add a "email me a login link" affordance to your existing login screen. Users on shared machines, or with password managers, will still want the password path. This also gives you a fallback if the mail pipeline degrades.

Layer throttling at the route. Put throttle:5,1 on the send endpoint (per email and per IP if you can — Laravel's default is IP-only). Without it the endpoint is an email-bombing and account-enumeration oracle. Pair it with the package's own expiry setting, and keep expiry short — 10–15 minutes is the sane range.

Customize the notification, not the internals. Publish or extend the notification class and override the mail subject/line and the URL TTL in one place. If the config lets you swap the notification class, do that — it survives package updates better than editing vendor files.

Queue the notification. Implement ShouldQueue on your subclass (or set the queue in config) so the HTTP request doesn't block on SMTP. This matters more than usual because the link must arrive while the token is still valid.

Handle the post-login redirect explicitly. Magic links often land users on a deep-link intent (e.g., the page they were trying to reach). Store intended in the session before sending, and let the package's redirect hit redirect()->intended().

SPA / stateless variant. If you have a separate frontend, have the magic link route authenticate and then redirect to your SPA with a short-lived signed exchange token, rather than trying to share the session cookie. Don't return a plain API token from a URL that also lands in the browser history.

Gotchas and Tips

  • Age is the real risk. A 2020 release predates Laravel 9's container and Notification changes. Before committing, run the package's tests (if any) or a smoke test on your Laravel version. If composer require conflicts, fork it, widen the illuminate/* constraint, and fix the type errors — the codebase is small enough that this is an afternoon, not a week.
  • Double expiry layers. Laravel's signed middleware has its own expires parameter; the package likely has a config value too. If they disagree, your UI will say "valid for 15 minutes" while links die at 60, or worse, live longer than advertised. Set both from one config value.
  • Signed URLs are replayable. A Laravel signed URL stays valid until it expires — clicking it twice logs you in twice. If you need strictly single-use links, add a magic_token column (or a cache key) that you null out on consumption. Decide whether that's a requirement before you ship.
  • Host mismatch behind proxies. Signed URL validation compares the full URL. Behind a load balancer or on Laravel Vapor/Forge with a proxy, configure TrustProxies and URL::forceScheme('https') or every link will 403 with "invalid signature" — a confusing failure that looks like a broken package.
  • Session regeneration. Confirm the package calls $request->session()->regenerate() after Auth::login(). If it doesn't, wrap the callback route or fork the controller; session fixation on an auth endpoint is not negotiable.
  • User deleted between send and click. The callback resolves the user from the URL. If the account was removed or deactivated in the interim, make sure you get a clean redirect to login, not a 500 on a null user.
  • Deactivation and login state. Check is_active / soft-deletes after the signature validates but before Auth::login(). It's easy to leave this out because the happy path works.
  • config:cache will bite you. Any edits to config/magic-auth.php need a php artisan config:clear in dev. Publish the config in the same PR as the install so it's tracked in git and doesn't mysteriously revert.
  • Extension points to note before you customize: the notification class, the redirect target, the route middleware group, and the expiry — these are typically config-exposed. Everything else (the controller, the route definitions) is a fork candidate, so minimize how much you touch. With 15 stars and zero dependents, assume you are the maintainer of your copy; vendor it into your own namespace if this becomes load-bearing.
  • Threat model it honestly. Magic links are bearer tokens in an email inbox. They're fine for consumer apps and internal tools; they're a poor fit if the email account is the weaker credential, or if you need 2FA-style separation of factors.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource