English | 简体中文
A Laravel package for OIDC (OpenID Connect) authentication with PKCE support. Architecture-agnostic — works with Blade, Livewire, Inertia, or any Laravel stack.
- OIDC Authorization Code Flow with PKCE
- Pluggable authentication strategy via
OidcAuthenticatorinterface - Automatic user provisioning from OIDC claims
- Flexible user mapping configuration
- Token revocation and SSO logout support
- Rate limiting on all endpoints
- Event system for authentication lifecycle
- PHP 8.2+
- Laravel 11.x or 12.x
- Persistent session driver (redis, database, file)
composer require admin9/laravel-oidc-client
php artisan vendor:publish --tag="oidc-client-config"
php artisan vendor:publish --tag="oidc-client-migrations"
php artisan migrateAdd to .env:
OIDC_AUTH_SERVER_HOST=https://auth.example.com
OIDC_CLIENT_ID=your-client-id
OIDC_CLIENT_SECRET=your-client-secret
OIDC_REDIRECT_URI=http://localhost:8000/auth/callbackUpdate app/Models/User.php:
protected $fillable = [
'name',
'email',
'password',
'oidc_sub',
'auth_server_refresh_token',
];
protected $hidden = [
'password',
'remember_token',
'auth_server_refresh_token',
];
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
'auth_server_refresh_token' => 'encrypted',
];
}The package registers these routes:
| Method | URI | Description |
|---|---|---|
| GET | /auth/redirect |
Start OIDC flow |
| GET | /auth/callback |
Handle callback, create session, redirect |
- User visits
/auth/redirect— redirected to your OIDC provider - After authentication, the provider redirects back to
/auth/callback - The package exchanges the authorization code for tokens, fetches user info, and creates/updates the local user
- The configured
OidcAuthenticatorhandles login (default: web session guard) and returns a response
Browser Your App OIDC Provider
│ │ │
├── GET /auth/redirect ──→ │ │
│ ├── Generate state + PKCE │
│ ├── Store in session │
│ ←── 302 Redirect ──────┤ │
├──────────────────────────────── Authorization ──────→ │
│ │ ├── User authenticates
│ ←───────────────────────────── 302 + code ──────────┤
├── GET /auth/callback ──→ │ │
│ ├── Validate state │
│ ├── Exchange code → tokens ─→│
│ │←── access_token ───────────┤
│ ├── Fetch userinfo ─────────→│
│ │←── user claims ────────────┤
│ ├── Find/create local user │
│ ├── OidcAuthenticator │
│ ←── Response ───────────┤ │
<a href="/auth/redirect">Login with SSO</a>Authentication errors are flashed to the session:
@if (session('oidc_error'))
<div class="alert alert-danger">
Authentication failed: {{ session('oidc_error_description') }}
</div>
@endifCreate a logout controller using OidcService:
use Admin9\OidcClient\Services\OidcService;
public function logout(Request $request, OidcService $oidcService)
{
$user = $request->user();
$oidcService->revokeAuthServerToken($user);
Auth::guard('web')->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
if ($oidcService->isOidcUser($user)) {
return redirect($oidcService->getSsoLogoutUrl());
}
return redirect('/');
}By default, the package uses SessionAuthenticator which logs in via Laravel's web guard. For SPA/JWT scenarios, implement the OidcAuthenticator interface:
use Admin9\OidcClient\Contracts\OidcAuthenticator;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class JwtAuthenticator implements OidcAuthenticator
{
public function authenticate(Request $request, mixed $user, array $tokens, array $userInfo): Response
{
$jwt = /* generate your JWT */;
return response()->json(['token' => $jwt]);
}
}Register it in config/oidc-client.php:
'authenticator' => \App\Services\JwtAuthenticator::class,The package dispatches two events during the authentication lifecycle:
| Event | Properties | When |
|---|---|---|
OidcUserAuthenticated |
$user, $userInfo, $isNewUser |
After successful authentication |
OidcAuthFailed |
$errorCode, $errorMessage |
When authentication fails |
Example listener:
// app/Listeners/LogOidcLogin.php
use Admin9\OidcClient\Events\OidcUserAuthenticated;
class LogOidcLogin
{
public function handle(OidcUserAuthenticated $event): void
{
logger()->info('OIDC login', [
'user_id' => $event->user->getKey(),
'new' => $event->isNewUser,
]);
}
}OIDC_REDIRECT_URL=/dashboard # Where to redirect after login (default: /dashboard)
OIDC_POST_LOGOUT_REDIRECT_URL=/ # Where Auth Server redirects after SSO logout (default: /)- Configuration - All config options and environment variables
- Troubleshooting - Common issues and solutions
MIT