toniel / laravel-keycloak-socialite
Reusable Keycloak Socialite authentication for Laravel applications.
Package info
github.com/toniel/laravel-keycloak-socialite
pkg:composer/toniel/laravel-keycloak-socialite
Requires
- php: ^8.2
- illuminate/contracts: ^12.0|^13.0
- illuminate/support: ^12.0|^13.0
- laravel/socialite: ^5.27
- socialiteproviders/keycloak: ^5.3
Requires (Dev)
- mockery/mockery: ^1.6
- orchestra/testbench: ^10.0|^11.0
- phpunit/phpunit: ^11.0|^12.0
This package is auto-updated.
Last update: 2026-07-29 10:54:32 UTC
README
Reusable Keycloak Socialite authentication for Laravel applications. Provides a drop-in Keycloak SSO integration with redirect, callback, logout, and backchannel logout routes — configurable and decoupled from any specific User model or permission system.
Features
- SSO Login — Redirect to Keycloak, callback with auto-register
- Silent Logout — Logout from Keycloak without confirmation page (via
id_token_hint) - Backchannel Logout — When user logs out from any app, all other apps in the ecosystem are logged out automatically
- Cross-app SSO — Login once, access all apps in the same Keycloak realm
- Configurable IDP Hint — Skip Keycloak login screen, go directly to Google/GitHub/etc
- Event-driven — Hook into login, registration, and failure events
Requirements
- PHP 8.2+
- Laravel 12+ / 13+
- A running Keycloak server (tested with v26+)
Installation
composer require toniel/laravel-keycloak-socialite
Publish the configuration file:
php artisan vendor:publish --tag=keycloak-socialite-config
Publish the migration (optional — only if your users table doesn't already have the columns):
php artisan vendor:publish --tag=keycloak-socialite-migrations php artisan migrate
Environment Variables
Add these to your .env file:
KEYCLOAK_BASE_URL=https://auth.example.com KEYCLOAK_REALM=your-realm KEYCLOAK_CLIENT_ID=your-client-id KEYCLOAK_CLIENT_SECRET=your-client-secret KEYCLOAK_REDIRECT_URI=http://your-app.test/auth/keycloak/callback # Optional KEYCLOAK_IDP_HINT=google # Skip Keycloak login screen, go directly to an IDP KEYCLOAK_AUTO_REGISTER=true # Create users automatically on first login KEYCLOAK_REMEMBER_LOGIN=false # Disable for SSO — let Keycloak manage session KEYCLOAK_REDIRECT_URL=/dashboard # Fallback post-login redirect # Logout KEYCLOAK_LOGOUT_MODE=keycloak # 'keycloak' (destroy SSO session) or 'local' (app only) KEYCLOAK_LOGOUT_REDIRECT=/ # Where to redirect after logout (must be registered in Keycloak) KEYCLOAK_BACKCHANNEL_LOGOUT=true # Enable backchannel logout endpoint
Setup Your User Model
Your User model must implement KeycloakAuthenticatable. Use the included trait for defaults:
<?php namespace App\Models; use Illuminate\Foundation\Auth\User as Authenticatable; use Toniel\LaravelKeycloakSocialite\Contracts\KeycloakAuthenticatable; use Toniel\LaravelKeycloakSocialite\Traits\HasKeycloakIdentity; class User extends Authenticatable implements KeycloakAuthenticatable { use HasKeycloakIdentity; protected $fillable = [ 'name', 'email', 'password', 'keycloak_id', 'keycloak_avatar', ]; }
Routes
The package automatically registers these routes:
| Method | Default URI | Named Route | Description |
|---|---|---|---|
| GET | /auth/keycloak |
login.keycloak |
Redirect to Keycloak login |
| GET | /auth/keycloak/callback |
login.keycloak.callback |
Handle OAuth callback |
| GET | /auth/keycloak/logout |
logout.keycloak |
Logout from app + Keycloak |
| POST | /auth/keycloak/backchannel-logout |
login.keycloak.backchannel-logout |
Receive logout signal from Keycloak |
To disable auto-registration and define your own routes, set routes.enabled to false in config.
Logout
How Logout Works
When a user logs out:
- Local session destroyed — Laravel session + remember token invalidated
- Redirect to Keycloak — with
id_token_hintfor silent logout (no confirmation page) - Keycloak destroys SSO session — user is logged out from Keycloak
- Backchannel notification — Keycloak POSTs to all other apps to destroy their sessions
- Redirect back — user lands on your app's home/login page
User clicks Logout in App A
→ App A destroys local session
→ Redirect to Keycloak logout (silent — no confirmation page)
→ Keycloak destroys SSO session
→ Keycloak POSTs logout_token to App B, App C, etc (backchannel)
→ App B, App C destroy their local sessions
→ Keycloak redirects back to App A's post_logout_redirect_uri
→ ✅ User is logged out everywhere
Silent Logout (no Keycloak page)
The package automatically captures and stores the id_token during login. On logout, it sends id_token_hint to Keycloak — this tells Keycloak to process the logout immediately without showing a confirmation page.
Requirements:
KEYCLOAK_LOGOUT_MODE=keycloak- User must have logged in via the Keycloak callback (not via remember cookie)
Backchannel Logout
Backchannel logout enables cross-app session kill. When a user logs out from any app in your ecosystem, Keycloak notifies all other apps to destroy that user's session.
How it works:
- Keycloak sends a
POSTrequest with alogout_token(JWT) to each app's backchannel endpoint - The package decodes the token, finds the user by their
keycloak_id, and deletes their sessions from the database
Keycloak Admin Setup (per client):
- Go to Clients → [your client] → Settings → Logout settings
- Turn OFF "Front-channel logout"
- Set "Backchannel logout URL":
https://your-app.com/auth/keycloak/backchannel-logout - Turn ON "Backchannel logout session required"
Note: If Keycloak runs in Docker, it must be able to reach your app's URL. Add
extra_hoststo your docker-compose:services: keycloak: extra_hosts: - "your-app.test:host-gateway"
Supported session drivers: database (recommended). For file driver, the package invalidates the remember token as fallback.
Logout Configuration
| ENV | Default | Description |
|---|---|---|
KEYCLOAK_LOGOUT_MODE |
keycloak |
keycloak = destroy SSO session, local = app session only |
KEYCLOAK_LOGOUT_REDIRECT |
/ |
Post-logout redirect URI (must be absolute or will be prefixed with APP_URL) |
KEYCLOAK_LOGOUT_ID_TOKEN_HINT |
true |
Send id_token for silent logout |
KEYCLOAK_BACKCHANNEL_LOGOUT |
true |
Enable/disable backchannel endpoint |
Keycloak client configuration required:
- Valid Post Logout Redirect URIs:
https://your-app.com/*
Events
KeycloakUserAuthenticated
Fired when an existing user logs in via Keycloak.
use Toniel\LaravelKeycloakSocialite\Events\KeycloakUserAuthenticated; Event::listen(KeycloakUserAuthenticated::class, function (KeycloakUserAuthenticated $event) { // $event->user — the Eloquent User model // $event->socialiteUser — the Laravel\Socialite User // Override the redirect URL: $event->redirectUrl = '/custom-dashboard'; });
KeycloakUserCreated
Fired when a new user is created from Keycloak data.
use Toniel\LaravelKeycloakSocialite\Events\KeycloakUserCreated; Event::listen(KeycloakUserCreated::class, function (KeycloakUserCreated $event) { $event->user->assignRole('employee'); });
KeycloakAuthenticationFailed
Fired when authentication fails.
use Toniel\LaravelKeycloakSocialite\Events\KeycloakAuthenticationFailed; Event::listen(KeycloakAuthenticationFailed::class, function (KeycloakAuthenticationFailed $event) { // $event->reason, $event->exception $event->errorRedirect = '/custom-error-page'; });
Configuration Reference
| Key | Default | Description |
|---|---|---|
user_model |
App\Models\User |
FQCN of your User model |
redirect_url |
/dashboard |
Fallback post-login redirect |
idp_hint |
google |
Keycloak kc_idp_hint parameter (set empty to disable) |
auto_register |
true |
Create users on first login |
remember_login |
false |
Disable for SSO apps (let Keycloak manage session) |
routes.enabled |
true |
Auto-register routes |
logout.mode |
keycloak |
keycloak or local |
logout.redirect_url |
/ |
Post-logout redirect (resolved to absolute URL) |
logout.id_token_hint |
true |
Send id_token for silent logout |
logout.backchannel_enabled |
true |
Enable backchannel logout endpoint |
Important Notes
Why remember_login should be false for SSO
In an SSO ecosystem, session management should be handled by Keycloak — not by Laravel's remember cookie. If remember_login is true:
- User can bypass Keycloak callback on subsequent visits (via cookie)
id_tokenwon't be stored in session → logout requires confirmation page- Backchannel logout can't fully work (user re-authenticates via cookie)
Google/IDP Session Behavior
If users log in via an external IDP (Google, GitHub, etc.) through Keycloak, logging out from Keycloak does not log them out from the IDP. If the IDP session is still active, Keycloak may silently re-authenticate the user on next access. This is expected SSO behavior.
Testing
composer test
License
MIT — see LICENSE.md.