Weave Code
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 Auth Laravel Package

joe-404/laravel-auth

Config-driven, drop-in auth for Laravel 12/13: JSON API for registration with OTP/magic-link verification, login, refresh tokens, password reset, Google OAuth, multi-session/device fingerprinting, long-lived API tokens, account status workflows, and referrals.

View on GitHub
Deep Wiki
Context7
v2.7.1
v2.7.0

⚠️ v2.7.0 was tagged on the pre-merge commit and ships v2.6.1-equivalent code. The intended v2.7 work is split across v2.7.1 (security hardening), v2.7.2 (concurrency hardening), and v2.7.3 (atomic 2FA challenge + admin referral gate + deletion-snapshot privacy + revoke step-up) — all of which supersede this release. Please upgrade to v2.7.3.

v2.6.1

v2.6.1 — Security hardening

A focused security pass over the v2.6.0 surface. Closes several 2FA-bypass paths and tightens defaults. No new migrations. Mostly backward-compatible — see the two behavior-change notes at the end.

Security fixes

  • Social login no longer bypasses 2FA — a user with 2FA enrolled who signs in with Google now gets a challenge_token and must complete /auth/2fa/challenge, exactly like password login.
  • Social login runs the full account-status gate — suspended/disabled are rejected, deactivated auto-reactivates (was only checking is_active).
  • Password-reset auto-login no longer bypasses 2FA — a 2FA user gets a challenge_token; the token is issued only after the second factor passes.
  • Email OTP / magic-link tokens stored as keyed HMAC-SHA256 (app-key pepper) instead of plain SHA-256 — a leaked DB can't reverse low-entropy codes offline.
  • Tokens removed from redirect query strings — verify / reset / social-link redirects now carry tokens in the URL fragment (#…), never sent to servers, logs, or Referer.
  • auth.active enforced on default authenticated + admin routes — a mid-session suspension takes effect on the next request, not at token expiry.
  • Step-up protection (new auth.step-up middleware) on destructive 2FA actions (remove method, regenerate backup codes) and phone change. Mode is config-driven (two_factor.step_up_mode: password_confirm default | two_factor). Admin status-change step-up is opt-in (account.status.require_step_up, default off).
  • Responses defensively strip password / remember_token even if the host User model omits them from $hidden.

Behavior changes

  • Default password.min_length raised 8 → 15 (NIST SP 800-63B-4 single-factor posture; composition rules stay off). Affects only new passwords. Override with AUTH_PASSWORD_MIN (hard floor 8).
  • Post-redirect tokens move to the URL fragment — SPA clients must read them from window.location.hash instead of the query string.

Upgrade

  composer update joe-404/laravel-auth   # no migrations

Set AUTH_PASSWORD_MIN=8 to keep the old password floor.

v2.6.0

v2.6.0 — Phone, 2FA & Trusted Devices

Additive release — existing users without 2FA enrolled see no flow changes.

Added

  • Phone capture + verification (SMS / voice / WhatsApp) via a pluggable driver system: log (dev only), infobip, messagecentral, twilio, firebase, or custom.
  • Two-factor authentication: TOTP (authenticator app), email OTP, SMS OTP — enroll multiple, pick any at login. Single-use backup codes.
  • Login challenge flow: once 2FA is enrolled, login returns a challenge_token; POST /auth/2fa/challenge issues the real token. Method switching + resend.
  • Trusted devices with time-based trust levels (low/medium/high). 2FA bypass requires BOTH the device fingerprint AND a server-issued X-Trusted-Device-Token — fingerprint alone never bypasses.
  • Require2FA middleware (auth.2fa) for step-up on sensitive endpoints, with block / force_enroll / password_confirm (sudo) fallbacks.
  • Social profile completion: OAuth users missing required fields finish via POST /auth/social/complete (same rules as the email flow).
  • Request::authContext(), 8 new events, version-stamped migrations, and php artisan auth:install --upgrade.

New dependencies

  • pragmarx/google2fa ^8.0, bacon/bacon-qr-code ^3.0

Upgrade

composer update joe-404/laravel-auth
php artisan auth:install --upgrade

Then add phone, phone_verified_at, two_factor_required to your User $fillable. Full guide: docs/upgrading.md (v2.6 section).

v2.5.1

Security and correctness pass on the refresh-token flow, plus a handful of hardening fixes around device fingerprinting, error responses, and config validation. No breaking changes, no migrations.

Fixed

  • Refresh re-validates account status — suspended / disabled / soft-deleted / unverified users can no longer rotate tokens for the lifetime of the refresh window.
  • Refresh rotation is now atomic — token row is lockForUpdate-selected; any presentation of a consumed refresh token revokes the whole family (RFC 6749 §10.4 strict rotation). The family-revoke runs after the rotation transaction commits so its writes cannot be rolled back.
  • Refresh updates the session recordauth_sessions_extended.sanctum_token_id is now re-pointed at the new access token, fixing /auth/sessions, session revocation, and last-active tracking after the first refresh.
  • Exception renderer honors AUTH_ROUTES_PREFIX — custom prefixes (api/v1/auth, etc.) now get the JSON envelope on validation/auth errors.
  • Frontend magic-link URL is validated — missing/malformed frontend_verify_url / frontend_reset_url now throws AuthConfigurationException instead of producing broken emails.
  • ApiTokenAuth no longer leaks raw exception messages — unknown errors are logged and replaced with a generic "Invalid API token.".
  • X-Browser-Fingerprint is format-validated — must be a hex digest within [32, 128] chars, otherwise treated as absent.
  • GeoIP lookup queued + HTTPS — moved into the new BackfillSessionLocation job; default endpoint is https://ip-api.com/json/{ip} and is overridable.

Added

  • AuthConfigurationException (typed exception for programmer-facing misconfig).
  • BackfillSessionLocation job (async GeoIP).

New optional config keys (all have safe defaults)

  • verification.required_for_refresh (default true)
  • referral_code.browser_fingerprint_min_length (default 32)
  • referral_code.browser_fingerprint_max_length (default 128)
  • device.location_endpoint (default https://ip-api.com/json/{ip})
  • device.location_queue (default default)

Upgrading

composer require joe-404/laravel-auth:^2.5
php artisan vendor:publish --tag=auth-config --force

A queue worker must be running for country / city to populate on session rows when device.resolve_location=true.

See CHANGELOG.md and docs/upgrading.md for the full notes.

v2.5.0

Permanent device history, browser/mobile fingerprinting, and a full referral code system with config-driven anti-abuse detection.

⚠ Beta notice: This package is still under active testing. Please report any issues you encounter.

Full upgrade guide: https://github.com/joe-nassar-tech/laravel-auth/blob/main/docs/upgrading.md#upgrading-to-v250-from-v24x


Added

Permanent device history

  • Every successful login upserts a row in auth_user_devices. Records survive logout and session revocation.
  • GET /auth/devices — list every historical device with first/last seen timestamps.
  • DELETE /auth/devices/{id} — forget a device and revoke any active sessions with a matching fingerprint.

Browser and mobile fingerprinting

  • Reads fingerprint_hash from X-Browser-Fingerprint header (browser/SPA) or device_id in X-Device-Info header (mobile).
  • Stored on both auth_sessions_extended and auth_user_devices.
  • device_signature de-duplicates records across reinstalls: fingerprint hash → device code SHA-256 → browser+OS+platform SHA-256.

Referral code system

  • Auto-generate referral codes at registration (configurable length, uppercase, custom generator via ReferralCodeGeneratorContract).
  • POST /auth/referrals/redeem — submit a code within AUTH_REFERRAL_REDEEM_WINDOW minutes.
  • GET /auth/referrals / GET /auth/referrals/stats — user-facing referral data.
  • GET /auth/admin/referrals / PATCH /auth/admin/referrals/{id} — admin management.
  • Anti-abuse detection using full device history (not just latest session). Per-signal policy (block / flag / ignore) for same IP, same device, or both.
  • Client restrictionAUTH_REFERRAL_ALLOWED_CLIENTS=web|mobile|both. Wrong client type fails silently.
  • Pluggable reward handler via ReferralRewardHandlerContract. Failure reverts referral to pending for retry.
  • Three new events: ReferralCreated, ReferralRedeemed, SuspiciousReferralDetected.

New translation keys — errors: referral_*, device_not_found. Messages: referral_*, devices_retrieved, device_forgotten.

Documentationdocs/referral-codes.md — 15-section guide covering all flows, anti-abuse scenarios, browser/mobile fingerprint integration, reward handler examples, and admin override workflow.


Migrations

Migration Creates / Alters
2026_05_20_000001_create_referrals_table referrals table
2026_05_20_000002_add_fingerprint_hash_to_auth_sessions_extended fingerprint_hash column
2026_05_20_000003_create_auth_user_devices_table auth_user_devices table
v2.4.7

Added

  • Orphaned session cookie cleanup. POST /auth/session/destroy-orphan is an unauthenticated endpoint for SPAs to call when /auth/me returns 401 but a stale session cookie is still present (e.g. after a manual database wipe or violated lifecycle). Forces the cookie to expire without requiring a valid token.
v2.4.6

Fixed

  • POST /auth/email/resend-verification returned an incorrect response body when the user's existing OTP had already expired. Now correctly returns the verification_resent message in all code paths.
v2.4.5

Added

  • EmailVerified event. Fired after email verification completes at the end of the registration flow. Listeners can use this event to trigger post-verification workflows (welcome emails, onboarding jobs, etc.).
v2.4.3

Changed

  • Complete documentation rewrite. All files under docs/ were rewritten with full detail: installation walkthrough, configuration reference for every key, customization guide for all six contracts, events reference, localization guide, account status and deletion guides, and upgrading notes.
  • docs/AI_Context.md added — full repo snapshot for AI assistants.
  • docs/ excluded from Composer archive. Production installs no longer include documentation files.
v2.4.2

Fixed

  • MySQL strict mode migration error. The deleted_accounts table migration declared deleted_at and scheduled_purge_at without a default value, which MySQL strict mode rejects with SQLSTATE[22007]. Both columns are now ->nullable().

Affects anyone running MySQL in strict mode (sql_mode includes STRICT_TRANS_TABLES) on v2.4.0 or v2.4.1.

v2.4.1

Added

  • Configurable route prefix. Package routes can now be mounted at any URL prefix. Set AUTH_ROUTES_PREFIX=api/v1/auth in .env or routes.prefix in config/auth_system.php. Previously hardcoded to auth.
  • Route auto-register toggle. Set AUTH_ROUTES_REGISTER=false to disable automatic route mounting and include the route file manually inside your own Route::group(). Useful for host apps that wrap all routes in a versioned API group.

No breaking changes. Run php artisan vendor:publish --tag=auth-config --force to pick up the new config keys.

v2.4

Account lifecycle: configurable status workflow, timed bans, self-service deactivation, soft-delete with grace-period auto-restore, and a full admin audit log.

Full upgrade guide: https://github.com/joe-nassar-tech/laravel-auth/blob/main/docs/upgrading.md#upgrading-to-v24x-from-v23x

Added

  • Account status system. Five statuses: active, suspended, disabled, deactivated, deleted. New auth.active middleware enforces the status mid-session.
  • Admin status endpoints. GET|POST /auth/admin/users/{id}/status — suspend, disable, restore users. Changes optionally revoke all sessions.
  • Timed bans. Accept expires_at or duration_minutes. Auto-unban fires via lazy revert on every status read and a scheduled sweep every 5 minutes.
  • Self-service account deactivation. POST /auth/account/deactivate — Instagram-style pause, auto-reactivates on next login.
  • Account deletion with 30-day grace period. DELETE /auth/account — login within the grace window auto-restores. Purge worker nulls unique columns after grace expires.
  • Account audit log. Every status transition written to account_status_logs. Admin note endpoint at POST /auth/admin/users/{id}/notes. History at GET /auth/admin/users/{id}/status/history.
  • HasAccountStatus trait — convenience methods isActive(), isSuspended(), isDisabled(), isDeactivated(), isDeleted().
  • Events: AccountStatusChanged, AccountDeleted, AccountRestored, AccountPurged.
  • Six notification classes for account lifecycle emails, all with publishable Blade views and FQCN config overrides.
  • Docs: docs/account-status.md, docs/account-deletion.md.

Note: Tagged as v2.4 (without .0 patch suffix). Patch suffix added from v2.4.1 onwards.

v2.3.2

Fixed

  • POST /auth/email/resend-verification did not create a new OTP record when the user's existing OTP had already expired, causing the resent email to contain an invalid code. The controller now forces a fresh OTP before sending.
v2.3.1

Fixed

  • InstallCommand rewrite. php artisan auth:install now runs steps in the correct dependency order, prints clear error messages when a required package is missing, and is safe to re-run on an already-installed app.
  • AuthRolesSeeder pre-flight. Now checks for the roles table before running and prints a helpful hint instead of crashing with a raw SQL error.
  • Minor fix to device column handling in AuthSessionExtended.
  • docs/installation.md added.
v2.3.0

Customisation and localization pass. Every user-facing string flows through Laravel's translation system. Three opt-in registration customisation features added.

Added

  • Multi-language support. Every controller response message and exception message resolves via a three-step pipeline: static config override → per-locale translation file → built-in English fallback. Publish with php artisan vendor:publish --tag=auth-lang. English and Arabic ship out of the box.
  • config('auth_system.errors') block — 26 keys for static, locale-independent error message overrides.
  • Extra-field validation messages. registration.extra_fields_messages — standard Laravel field.rule => message map for extra_fields_rules.
  • Extra-field transformers. registration.extra_fields_transformers — derive or normalise a field value post-validation without writing a controller (e.g. username_normalized = strtolower(username)).
  • Referral code generation. When auth_system.referral_code.enabled=true, generates a unique referral code per new user at registration. Swappable generator via ReferralCodeGeneratorContract.
  • AuthException carries errorKey + replacements for the translation pipeline.

Breaking change

AuthException constructor changed — see the upgrade guide.

v2.1.1

Fixed

  • ApiTokenAuth middleware did not reject tokens that had been revoked in auth_api_tokens when the underlying Sanctum token still existed. The middleware now checks the auth_api_tokens revocation status directly before allowing the request through.
  • Updated Postman collection to include all API token endpoints.
v2.1.0

Fixed

  • GET /auth/register/verify-magic/{token} was registered with the wrong HTTP method and returned 405 Method Not Allowed.
  • PasswordResetController did not correctly handle a signed URL that had already been consumed. Now returns a clean 422 instead of a 500.
  • EmailVerificationController::resend() did not return a response when the user was already verified. Now returns 200 with the verification_resent message.
v2.0.0

Security hardening pass. Several breaking changes — review carefully before upgrading.

Full upgrade guide: https://github.com/joe-nassar-tech/laravel-auth/blob/main/docs/upgrading.md#upgrading-to-v20x-from-v1x

Breaking changes

  • 3-step registration. Passwords are no longer accepted in POST /auth/register. Registration is now: initiate → verify OTP/magic → set password. This eliminates the pre-account takeover attack vector present in v1.x.
  • Refresh tokens moved to auth_refresh_tokens with atomic rotation and one-time use. Existing v1.x refresh tokens are invalid — users must log in again.
  • OTP codes stored as SHA-256 hashes. Existing plaintext OTP records will not match. Clear auth_otp_codes before upgrading.
  • EmailVerified eventsanctumToken parameter removed.
  • SocialAuthService::redirectUrl now requires Request $request as a second argument.
  • SocialAuthService::handleCallback now returns an array with a status key.
  • Social account auto-linking by email removed. Now requires inbox confirmation via signed link.
  • Magic-link endpoints now redirect to frontend_verify_url / frontend_reset_url.
  • AuthService::logoutAll now requires Request $request as a second argument.
  • Minimum supported Laravel raised to ^12.0.

Security fixes

  • OTP brute-force defense with failed_attempts tracking and max-attempts invalidation.
  • Refresh-token reuse detection with family-based rotation — stolen token reuse revokes the entire family.
  • Rate limiter no longer auto-clears on 2xx responses.
  • logoutAll preserves the calling token/session.
  • Mass-assignment denylist on extra_fields flowing into User::create().
  • finalizeRegistration wrapped in a DB transaction.
  • Constant-time forgotPassword for unknown emails.
v1.0.1

Fixed

Six bugs found during integration testing:

  • AuthServiceProvider did not correctly register package routes when the host app had custom route caching.
  • Missing use imports in two controller classes caused 500 errors in PHP 8.3 strict mode.
  • OtpService::create() did not clean up expired records before inserting a new one, causing unique constraint violations on high-traffic apps.
  • TokenService::issueRefreshToken() returned null on first-time logins.
  • SessionService did not handle a missing jenssegers/agent gracefully. Now falls back to the raw User-Agent string.
  • AuthRolesSeeder threw when the roles table did not exist. Now prints a clear error with instructions.
v1.0.0

joe-404/laravel-auth v1.0.0

A drop-in, config-driven authentication library for Laravel 13.
One composer require. One php artisan auth:install. Zero boilerplate.

What's included

Core authentication

  • POST /auth/register — sends OTP + magic link simultaneously, returns temp_token
  • POST /auth/register/verify-otp and GET /auth/register/verify-magic/{token}
  • POST /auth/login / POST /auth/logout / POST /auth/logout/all
  • GET /auth/me — user profile, roles, permissions, active session count

Password management

  • Forgot password via OTP (POST /auth/password/reset/otp) or signed magic link
  • Authenticated password change with optional logout_all

Session & device tracking

  • Browser, OS, device model, IP address, city, country per session
  • ~500-model device lookup from resources/devices.json
  • X-Device-Info header for mobile clients

API token system

  • Scoped, optionally expiring tokens with auth_at_ prefix
  • Full CRUD for users + admin management endpoints
  • ApiTokenAuth middleware with per-ability checks

Google OAuth

  • GET /auth/social/google/redirect + GET /auth/social/google/callback
  • Handles new user creation, existing user login, and account linking automatically

Real-time verification via Reverb

  • Broadcasts EmailVerified on auth.verification.{temp_token} when enabled
  • Frontend receives Sanctum token in real time without polling

Security hardening

  • Dual-layer rate limiting (per-IP + per-email) on all public endpoints
  • Account lockout with cumulative failure tracking
  • New-device email alerts via NewDeviceLoginNotification

Installation

composer require joe-404/laravel-auth
php artisan auth:install
php artisan migrate
php artisan db:seed --class=AuthRolesSeeder

See the README for full configuration reference and API documentation.

Requirements

Dependency Version
PHP ^8.2
Laravel ^13.0
laravel/sanctum ^4.0
laravel/socialite ^5.0
spatie/laravel-permission ^6.0
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky