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 Openid Connect Laravel Package

nl.idaas/laravel-openid-connect

Add OpenID Connect authentication to Laravel with a configurable OIDC client for standards-compliant identity providers. It handles provider discovery, authorization redirects, callback processing, and user login, making secure single sign-on easier to integrate.

View on GitHub
Deep Wiki
Context7

Getting Started

1. Install and swap out Passport

composer require nl.idaas/laravel-openid-connect

Because this is advertised as a drop-in replacement for Passport, the first decision is whether your app already uses laravel/passport. Check vendor/nl.idaas/laravel-openid-connect/composer.json:

  • If it replaces laravel/passport, remove laravel/passport from your require block and re-run composer update. Leaving both installed will double-register the /oauth/* routes and the passport guard, causing redirect loops and 404/405 confusion.
  • If it only extends Passport, keep Passport and just register the package's service provider.

2. Wire it up

  • Add the token trait (Laravel\Passport\HasApiTokens is typically reused) to your User model.
  • Point the API guard at auth:api with driver passport in config/auth.php.
  • Publish and review the package config/migrations:
php artisan vendor:publish --provider="NL\IDaaS\LaravelOpenIDConnect\LaravelOpenIDConnectServiceProvider"
php artisan migrate
  • Generate signing keys (php artisan passport:keys and passport:client if the package doesn't ship its own equivalents — check the README for the exact command names, as these have shifted across versions).

3. Register OIDC scopes

In AuthServiceProvider::boot() you must declare openid (and usually profile, email, offline_access) via Passport::tokensCan([...]). Without openid, every authorize request fails with invalid_scope — this is the #1 first-run stumbling block.

4. First use case: SSO for a first-party SPA

Create a public client (no secret, PKCE required), point it at your SPA's redirect URI, and verify the whole flow with oidcdebugger.com or oauth.tools:

  1. GET /.well-known/openid-configuration — confirm all endpoints and the issuer look right.
  2. GET /oauth/authorize?response_type=code&client_id=...&scope=openid profile email&redirect_uri=...&state=...&code_challenge=...
  3. Exchange the code at /oauth/token with the PKCE code_verifier.
  4. Call /oauth/userinfo with the access token to confirm claims.

Where to look first: the package's README, the published config/ file, and the route list (php artisan route:list --path=oauth).


Implementation Patterns

Retrofitting an existing Passport deployment. Existing oauth_clients rows generally survive because the schema is Passport-compatible, but the package may add OIDC-specific columns. Run php artisan migrate --pretend first, and snapshot the oauth_clients table before migrating in production. Existing clients keep working; you only need to ensure openid is an allowed scope for clients that will now request it.

Auth-code + PKCE for SPAs and mobile. Public client, exact-match redirect URI, response_type=code, S256 challenge, request offline_access if you need refresh tokens. Refresh tokens are only issued when offline_access is in the granted scopes — don't assume they come for free with openid.

One client per relying party. For partner integrations, register a dedicated client with a minimal scope set and a per-client redirect URI. This gives you per-RP revocation and clean audit trails. Pair it with the default consent screen (publish and override the authorization view if you need branding) so users see exactly which claims are being shared.

Custom claims. For anything beyond sub/name/email, override the userinfo response or hook the id-token claim assembly (the package typically exposes a builder or event). Keep claims stable: changing the sub value later will break account linking in every downstream RP. Decide early whether sub is a UUID, an opaque hash, or the raw user ID, and document it.

Testing in CI. For feature tests, use Passport::actingAs($user, ['openid']). For an end-to-end test of the flow, drive /oauth/authorize with a session cookie via $this->actingAs($user)->get(...), parse the Location header for code, then POST to /oauth/token with the PKCE verifier. Don't unit-test the discovery endpoint in isolation — fetch it once and assert issuer matches config('app.url').

Federation downstream. Point Kong, Traefik, NextAuth, or another OIDC consumer at your /.well-known/openid-configuration. Most clients auto-configure from discovery; the only manual step is registering the client ID/secret with them.


Gotchas and Tips

  • AGPL-3.0 is a serious constraint. This is not MIT. If you operate the service over a network (i.e., any SaaS use), the AGPL obliges you to make the complete corresponding source available to users, including your modifications. For most commercial products this requires legal sign-off or a commercial license from the maintainers. Evaluate this before you build anything on it.
  • Very low adoption signal. 65 stars and zero known dependents means you are effectively an early adopter. Pin an exact commit or version, and be prepared to vendor-fork for security patches — especially around JWT signing and claim validation.
  • Issuer mismatch breaks everything. The issuer in your discovery document must byte-for-byte match the iss claim in tokens and the value relying parties were configured with. Behind a load balancer or proxy, $request->getSchemeAndHttpHost() will fall back to http:// and cause silent invalid issuer errors. Set APP_URL correctly and force HTTPS (URL::forceScheme('https')) in a service provider.
  • openid scope must be registered. invalid_scope on authorize almost always means you forgot Passport::tokensCan(['openid' => ...]) or forgot to add the scope to the specific client.
  • nonce must be echoed in the id_token when the client sends one. Some lightweight OIDC implementations omit it; verify with a debugger if a SPA library rejects the id_token.
  • Opaque access tokens by default. Passport issues random-string access tokens, not JWTs. Relying parties that try to jwt.decode() the access token will fail — they must use /oauth/userinfo or introspection. If a downstream tool requires a JWT access token, verify the package (or a Passport extension) supports it before promising the integration.
  • Signing keys need a kid and shared storage. If you run multiple app servers, passport:keys must write to a shared volume, and JWKS must be served consistently. Rotating keys without advertising a new kid in JWKS will invalidate every token in flight.
  • Redirect URIs are exact-match. No wildcards per spec, and most OIDC libraries reject http://localhost in production mode. Configure separate clients for local dev and prod — don't reuse.
  • Client authentication method matters. Confidential clients typically use client_secret_basic; some consumers only implement client_secret_post. Public clients must use none with PKCE. If the token endpoint returns invalid_client, it's almost always this mismatch.
  • Reverse-proxy caching. Set Cache-Control on discovery and JWKS; relying parties cache by kid, and a stale JWKS is a common cause of "signature verification failed" after rotation.
  • Consent UI is your responsibility. The default authorize screen is bare; publish and restyle the view, and consider audit logging for consent grants — it's rarely provided out of the box and is often an audit requirement.
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.
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel