Installation
composer require knpuniversity/oauth2-client-bundle
Add the bundle to config/bundles.php (Symfony) or config/app.php (Laravel via Symfony bridge):
KnpU\OAuth2ClientBundle\KnpUOAuth2ClientBundle::class => ['all' => true],
Configure Providers
Edit config/packages/knpu_oauth2_client.yaml (Symfony) or config/oauth.php (Laravel):
knpu_oauth2_client:
clients:
github:
type: github
client_id: '%env(GITHUB_CLIENT_ID)%'
client_secret: '%env(GITHUB_CLIENT_SECRET)%'
redirect_route: connect_github_check
First Use Case: Login with GitHub
# config/routes.yaml
connect_github:
path: /connect/github
controller: KnpU\OAuth2ClientBundle\Controller\ConnectController::connectAction
OAuth2Authenticator in a controller:
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
use KnpU\OAuth2ClientBundle\Client\Provider\GithubClient;
public function login(ClientRegistry $clientRegistry)
{
return $clientRegistry->getClient('github')->redirect();
}
User Authentication Flow
$client = $clientRegistry->getClient('github');
return $client->redirect();
$user = $client->fetchUser();
// Save to DB or create session
Multi-Provider Support
Dynamically register providers in config/oauth.php:
'providers' => [
'github' => [
'type' => 'github',
'client_id' => env('GITHUB_ID'),
'client_secret' => env('GITHUB_SECRET'),
],
'google' => [
'type' => 'google',
'client_id' => env('GOOGLE_ID'),
'client_secret' => env('GOOGLE_SECRET'),
],
],
Custom User Mapping
Extend User entity or use a mapper:
use KnpU\OAuth2ClientBundle\Client\Provider\GithubUser;
public function connectGithub(GithubUser $user)
{
$account = $this->userManager->findBy(['email' => $user->getEmail()]);
if (!$account) {
$account = $this->userManager->create([
'email' => $user->getEmail(),
'name' => $user->getUsername(),
]);
}
return $account;
}
State Management Use the built-in state system to prevent CSRF:
# config/packages/knpu_oauth2_client.yaml
knpu_oauth2_client:
clients:
github:
state: true # Default: true
symfony/bridge to integrate with Laravel’s auth system:
use Symfony\Component\HttpFoundation\RedirectResponse;
use KnpU\OAuth2ClientBundle\Client\OAuth2Client;
public function handleOAuth(OAuth2Client $client)
{
$user = $client->fetchUser();
Auth::loginUsingId($user->getId()); // Custom logic
return redirect('/dashboard');
}
// After OAuth login, issue a Passport token
$token = $user->createToken('oauth_token')->accessToken;
State Mismatch Errors
state parameter in redirects.state: true in config and regenerate .env secrets if needed.Provider-Specific Quirks
redirect_uri to match exactly (including trailing slashes).scopes explicitly defined:
google:
scopes: ['email', 'profile']
Session Handling
session.storage.handler_id is set.session(['oauth_state' => $client->getState()]);
Token Expiry
refreshToken():
$client->refreshToken($refreshToken);
knpu_oauth2_client:
debug: true # Logs OAuth requests/responses
dd($client->getRedirectUri()) to verify URLs.Custom Providers
Extend OAuth2Client for unsupported providers:
use KnpU\OAuth2ClientBundle\Client\Provider\GenericProvider;
class CustomProvider extends GenericProvider {
public function getBaseUrl() { return 'https://custom-api.com'; }
public function getResourceOwnerDetailsUrl($token) { ... }
}
Event Listeners
Listen to KnpUOAuth2ClientBundle.Event\AuthEvent for post-login actions:
use KnpU\OAuth2ClientBundle\Event\AuthEvent;
public function onAuth(AuthEvent $event) {
$user = $event->getUser();
// Custom logic (e.g., sync roles)
}
Laravel Service Providers Bind the registry to Laravel’s container:
public function register()
{
$this->app->bind('knpu.oauth2.client.registry', function ($app) {
return new ClientRegistry([...], $app['http_client']);
});
}
How can I help you explore Laravel packages today?