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

Auth0 Symfony Laravel Package

elvi/auth0-symfony

A maintained fork of auth0/symfony that adds up-to-date fixes and changes while including everything supported by the main package. Integrates Auth0 authentication into Symfony apps with a familiar, compatible setup.

View on GitHub
Deep Wiki
Context7

Getting Started

Know what you're actually installing. elvi/auth0-symfony is a fork of auth0/symfony, not a Laravel package. There is no Auth0ServiceProvider, no publishable config/auth0.php, and no Auth0::fake() facade. If your application is Laravel-first, the day-to-day package you want is auth0/login (plus auth0/auth0-php for Management API work); reach for this fork only when you are working inside a Symfony service in the same estate, contributing a patch upstream, or deliberately borrowing a reference implementation of firewall/JWKS handling.

For a Symfony service that will actually run it:

composer require elvi/auth0-symfony

Then, in order of where to look first:

  1. vendor/elvi/auth0-symfony/src/ — confirm the bundle class namespace before registering it (Elvi\Auth0Symfony\Auth0Bundle in most of these forks; it may still be Auth0\Symfony\Auth0Bundle if the fork was shallow). A composer show elvi/auth0-symfony and a quick rg "class .*Bundle" saves an hour.
  2. config/bundles.php — register it, then populate config/packages/auth0.yaml under the auth0: root key (sdk:, authenticator:, authorizer:). The fork inherits the same config tree as upstream, so upstream's docs are the authoritative reference.
  3. config/packages/security.yaml — wire the auth0_authenticator guard to your firewall and add the bundle's auth0 user provider. This is the first real use case: log a user in via Auth0 and get a Symfony\Component\Security\Core\User\UserInterface back in the token storage.

Environment variables you'll set before anything boots:

AUTH0_DOMAIN=tenant.eu.auth0.com
AUTH0_CLIENT_ID=...
AUTH0_CLIENT_SECRET=...
AUTH0_COOKIE_SECRET=<32+ chars>
AUTH0_REDIRECT_URI=https://app.example.com/auth0/callback
AUTH0_MANAGEMENT_CLIENT_ID=...
AUTH0_MANAGEMENT_CLIENT_SECRET=...

The fastest sanity check is the bundle's built-in login/callback/logout routes — hit /auth0/login (or whatever prefix the fork registers) and confirm you come back authenticated. If that works, the SDK, session storage, and cookie handling are all correct and you can move on to your own controllers.

Implementation Patterns

1. Treat the package as two SDKs, not one. Authentication (OIDC login, session, logout) and Management (user CRUD, roles, M2M) are configured separately and fail independently. Wire the Management API credentials as a separate M2M application in Auth0 with only the scopes you need — never reuse the web app's client secret for Management calls. Typical service definition:

services:
  App\Service\Auth0Users:
    arguments:
      $management: '@auth0.management'   # check the exact service id in the fork

If the fork doesn't expose a convenient service alias, instantiate Auth0\SDK\API\Management yourself from %env(AUTH0_DOMAIN)% and a cached token — it's a thin HTTP wrapper and you lose little.

2. Sync-on-login, not sync-on-callback. The common pattern is a UserProvider that lazily creates the local row the first time an Auth0 identity appears, keyed on sub. Keep sub in a unique, indexed column and store the connection name alongside it:

$user = $this->users->firstOrCreate(
    ['auth0_sub' => $auth0User->getId()],
    ['email' => $auth0User->getEmail(), 'name' => $auth0User->getName()]
);

This survives connection changes, avoids a webhook dependency, and means a user row exists exactly when someone can actually log in.

3. Borrow the pattern, not the code, into Laravel. The pieces of this fork worth replicating in a Laravel app are small and portable:

  • JWKS caching. Fetch /.well-known/jwks.json, cache it under a key that includes the kid, and refresh on cache miss rather than on every request. auth0/auth0-php v8 does this for you; older flows in the Symfony SDK show the shape.
  • Cookie secret handling. The SDK encrypts its session cookie with cookie_secret; if you're proxying Auth0 sessions across a PHP monolith and a Symfony service, both need the same secret and compatible SameSite/Secure settings.
  • Token verification middleware. In Laravel this becomes a middleware('auth0.jwt') that calls Auth0::decode($bearer, $tokenVerifier) and resolves sub to an Eloquent user — the Symfony equivalent is an AbstractAuthenticator, and the fork's implementation is a decent template.

4. Machine-to-machine calls belong in a dedicated client. For service-to-service work, request a client_credentials token against https://{domain}/oauth/token with an audience and cache it until ~60s before expires_in. Do this in one class, not scattered through controllers, and give it its own Guzzle/Http instance with retry on 429.

5. Sharing config with Laravel. If a Laravel app and a Symfony service sit behind the same tenant, put the tenant config in environment variables with identical names and let each framework map them. Don't commit auth0.yaml values that differ from the Laravel side — divergence in redirect_uri or allowed callback URLs is the single most common cause of invalid_request / mismatching_state errors across a mixed stack.

6. Version-pin aggressively. This is a fork with 3 stars and no dependents; composer.json should pin the minor ("elvi/auth0-symfony": "~5.0") and your lockfile should be committed. If you need a newer Auth0 PHP SDK, you'll likely have to bump the fork's constraint yourself and open a PR — budget for that as maintenance, not as an incident.

Gotchas and Tips

It will not autowire in Laravel, and that's the point. No service provider, no config merge, no Facade. Any attempt to composer require this into a Laravel app and "just use it" produces a bundle class that never boots and config keys that are never read. Use auth0/login for the framework integration and auth0/auth0-php directly if you need lower-level control.

Fork drift is the real risk. The README's value proposition is "more up-to-date fixes than upstream," which is only true as long as someone is merging. Before adopting, diff against auth0/symfony at the same tag to see exactly what changed; if the diff is small, prefer upstream plus a patch file you control. Check whether the fork declares replace: {"auth0/symfony": "*"} — if not, having both installed produces two bundles fighting over the same service ids.

Management tokens expire. The Management API access token is valid for 24 hours; code that fetches one per request will hit /oauth/token rate limits under any real load. Cache it (Redis or the framework cache) with a TTL derived from expires_in, and never cache the token in the session.

Logout is a redirect, not a local operation. Clearing the local session leaves the Auth0 SSO cookie intact — the user is silently logged back in on the next /authorize. The Auth0-side logout requires a redirect to https://{domain}/v2/logout?client_id=...&returnTo=..., and returnTo must be in the tenant's Allowed Logout URLs or it is silently ignored. The bundle's logout controller handles this; hand-rolled logout is where most "logout doesn't work" tickets come from.

sub is connection-scoped. auth0|123 and google-oauth2|123 are different identities, and the same email can legitimately map to two sub values. A unique(email) constraint on your users table will cause a 500 the first time someone logs in with a second provider. Key on sub, allow duplicate emails, and handle linking deliberately.

JWKS staleness after key rotation. If you cache JWKS for a day and Auth0 rotates keys, tokens fail with signature verification failed for the remainder of the cache window. Cache indefinitely but key the entry by kid, so a miss forces a refetch. This is also the trick for debugging: a sudden wave of verification failures with no code deploy almost always means the cache wasn't kid-scoped.

Debug mode leaks tokens. The SDK's debug flag logs full tokens and session contents. If you enable it to chase a login problem, make sure it's env-gated (AUTH0_DEBUG=1 locally only) and never enabled in staging that shares logs with production.

Clock skew and azp/aud validation. The two most common verification failures in production are a 30-second clock drift between containers (fix: NTP, plus small leeway in the verifier) and a missing audience in the authorize request, producing an opaque ID token that downstream API middleware rejects. Log the decoded header (not the payload) when verification fails — it tells you immediately whether the token was even minted for you.

Extension points worth knowing. The bundle's user provider, the authenticator, and the session storage are all interface-backed and overridable via services.yaml; that's the correct place to inject your EntityManager-aware user factory rather than subclassing the bundle. For anything the bundle doesn't expose — custom claims, step-up auth, organization-scoped tokens — drop to auth0/auth0-php directly. The fork is a convenience layer, and fighting it is more expensive than bypassing it.

Verdict for a Laravel team: use this as a reading reference for how a mature framework integration wires Auth0 (firewall, JWKS cache, logout redirect, Management token lifecycle), and use auth0/login + auth0/auth0-php in your actual application. Adopt the fork itself only if you own the Symfony service it runs in and are prepared to maintain it.

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.
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
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