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

Login Laravel Package

auth0/login

Auth0 Laravel SDK integrates Auth0 into Laravel apps with no-code user authentication, extensive Management API support, and permissions-based routing access control. Requires Composer, a supported Laravel version, and an Auth0 account.

View on GitHub
Deep Wiki
Context7

Getting Started

Prerequisites: Laravel 11 or 12, PHP 8.2+, an Auth0 tenant, and the Auth0 CLI (optional but it removes 80% of the dashboard clicking).

Install into an existing app:

composer require auth0/login:^7 --update-with-all-dependencies
php artisan vendor:publish --tag auth0   # creates config/auth0.php

Minimum .env for a web (session) app:

AUTH0_DOMAIN=your-tenant.us.auth0.com
AUTH0_CLIENT_ID=...
AUTH0_CLIENT_SECRET=...
AUTH0_COOKIE_SECRET=...          # 32+ random chars, encrypts the session cookie
AUTH0_REDIRECT_URI=http://localhost:8000/callback

Add AUTH0_AUDIENCE=https://your-api-identifier if you also want the api guard (bearer-token routes). For Management API calls you need separate machine-to-machine credentials (AUTH0_MANAGEMENT_CLIENT_ID / _CLIENT_SECRET / _AUDIENCE) — see Gotchas.

In the Auth0 dashboard (or via auth0 apps create ... --callbacks ... --logout-urls ...) the Allowed Callback URLs must contain your AUTH0_REDIRECT_URI exactly, and Allowed Logout URLs must contain your app root.

Where to look first:

  1. config/auth0.php — the whole surface area lives here: routes, guards, session storage, caching, management credentials.
  2. docs/Configuration.md, docs/Management.md, docs/Deployment.md in the repo.
  3. Your tenant's Applications → Settings, to confirm callback/logout URLs match.

First use case (5 minutes): visit /login, get redirected to Auth0, come back, then read auth()->user():

// routes/web.php
Route::get('/dashboard', fn () => 'Hello '.auth()->user()->name)->middleware('auth');

No controller, no routes file entry, no guard registration — /login, /logout, and /callback are registered automatically inside the web middleware group, and the web/api guards are wired to Auth0 drivers at boot.

Implementation Patterns

1. Route protection is pure Laravel middleware. This is the core value of the package: you don't learn an Auth0 API, you use the middleware you already know.

Route::get('/private', fn () => 'logged in')->middleware('auth');
Route::get('/reports', fn () => 'allowed')->middleware('auth')->can('read:reports'); // needs RBAC

2. Reading the identity — session vs token. Same facade, different payloads.

// web.php — a hydrated user object
auth()->user()->name;    // from ID token / /userinfo
auth()->user()->email;
auth()->id();            // the Auth0 `sub`

// api.php — claims from the validated access token
auth()->id();                               // sub, e.g. "auth0|65f..."
$claims = auth()->user()->getAttributes();  // scope, permissions, custom claims

3. API authorization with a real bearer token. Use auth in routes/api.php and the api guard validates signature, issuer, audience and expiry against the cached JWKS.

Route::get('/api/example', function () {
    return response()->json([
        'sub'   => auth()->id(),
        'scope' => auth()->user()->getAttributes()['scope'] ?? '',
    ]);
})->middleware('auth');

Test it without a browser: auth0 test token --audience <identifier> --scopes "read:messages" then curl -H "Authorization: Bearer $TOKEN".

4. Permission checks over scopes. can('read:messages') evaluates the permissions claim (RBAC), not scope. Define Gates when you want friendlier names:

// AppServiceProvider::boot()
Gate::define('view-invoices', fn ($user) => in_array('read:invoices', $user->getAttributes()['permissions'] ?? []));

5. Management API as a service layer. Every endpoint class hangs off one facade method and returns PSR-7, so always call json():

use Auth0\Laravel\Facade\Auth0;

$user   = Auth0::management()->users()->get(auth()->id())->json();
$colors = ['red', 'blue', 'green'];

Auth0::management()->users()->update(auth()->id(), [
    'user_metadata' => ['favorite_color' => $colors[array_rand($colors)]],
]);

$roles = Auth0::management()->roles()->get()->json();

6. Bridging Auth0 users to your Eloquent models. auth()->user() is not an Eloquent model. For a local users table, either (a) implement Auth0\Laravel\Contract\Auth\User\Repository and swap it in config/auth0.php, or (b) listen for the SDK's login events and upsert:

// migration: $table->string('auth0_id')->unique();
Event::listen(\Auth0\Laravel\Events\LoginSuccess::class, function ($event) {
    User::updateOrCreate(
        ['auth0_id' => $event->user->getAuthIdentifier()],
        ['name' => $event->user->name, 'email' => $event->user->email]
    );
});

Then reference auth0_id (not id) as the foreign key everywhere.

7. Hybrid SPA + API app. Keep browser traffic in routes/web.php (session cookie, /login flow) and machine traffic in routes/api.php (bearer token). Because both guards are pre-registered, auth picks the right one by route group — but be explicit with auth:api on any API route you move into web.php.

8. Testing. For API tests, generate a token once with the CLI and replay it, or bypass the guard with $this->actingAs($fakeAuth0User); there is no password/loginUsing path since there's no local password. Keep a mocked Auth0 facade for Management API assertions (Auth0::shouldReceive('management')...) so tests never hit the network.

Gotchas and Tips

The /callback URL is checked character-for-character. A trailing slash, http vs https, or a different port is the #1 cause of "Callback URL mismatch". Same for logout. Keep both in .env and in the dashboard.

AUTH0_AUDIENCE is mandatory for the api guard. Without it the token validator has nothing to match and every bearer request 401s. It must equal the API Identifier, not its name.

can() needs RBAC enabled on the API. Permissions only appear in the access token when the API has RBAC on and the user has roles/permissions assigned. RBAC-off apps must fall back to checking the scope claim in custom middleware. Also: permissions lives in the access token, not the ID token — it's never available on web routes.

Management API credentials ≠ your app credentials. Use a separate Machine-to-Machine application authorized against the Management API, with the specific scopes you call. Using the web app's client ID/secret yields access_denied. And grant only the scopes you need — the SDK will happily try users:delete.

Management responses are PSR-7, not arrays. Auth0::management()->users()->get($id) returns a ResponseInterface; forgetting ->json() gives you an object that dd()s into a stream. Errors come back as non-2xx statuses with a JSON body in reason — wrap calls in try/catch for Auth0\SDK\Exception\NetworkException/ApiException.

Config and cookie secrets are load-bearing. After changing any AUTH0_* value, run php artisan config:clear (or config:cache again) — the SDK merges guard configuration at boot, so a stale cache can silently keep old credentials. Rotating AUTH0_COOKIE_SECRET logs everyone out; keep it identical across all nodes behind a load balancer, and use Redis/database sessions rather than file in multi-instance deployments.

/logout clears your Laravel session, not the Auth0 SSO session. If a user must be logged out of Auth0 itself (shared tenant, "sign out of everything"), add the federated-logout return URL to Allowed Logout URLs and enable federated logout in the config.

Route collisions and customization. If you already own /login or /callback, disable SDK route registration in config/auth0.php and build the flow yourself, or you'll get confusing 404/405s. The same config controls guard registration if you need a custom driver.

Token lifetime and refresh. Access tokens are short-lived. Refresh only works when the API grants offline_access (the CLI setup does) and refresh tokens are enabled in the app settings; otherwise long-idle browser tabs start 401ing. Consider a middleware that proactively refreshes or an inertia-style page reload.

JWKS caching and key rotation. Token validation uses cached signing keys. If you rotate tenant signing keys and requests suddenly fail signature verification, clear the SDK cache (configurable in config/auth0.php) before assuming a code bug.

auth()->id() is the sub, not a DB integer. Anything typed against int $userId — route model binding, foreign keys, audit columns — must change to string. This is the most common refactor cost when retrofitting Auth0 into an existing app.

Deployment checklist. HTTPS everywhere (the callback will be rejected over plain HTTP in production), APP_URL correct, SESSION_SECURE_COOKIE=true, SESSION_DOMAIN sane, and read docs/Deployment.md before going live — the SDK's defaults are dev-friendly, not production-hardened.

Version and exit-strategy notes. The package tracks Laravel majors tightly (v7 requires Laravel 11/12), so your Laravel upgrade cadence becomes your Auth0 SDK upgrade cadence. The surface area you actually depend on is small (three routes, two guards, one facade), which makes a future swap to firebase/php-jwt-style manual validation or another provider feasible — keep your Auth0-specific code inside a thin service class rather than scattered through controllers.

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.
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table