Installation:
composer require gnuckorg/da-oauth-client-bundle
Add to config/bundles.php:
return [
// ...
Gnuckorg\DaOAuthClientBundle\GnuckorgDaOAuthClientBundle::class => ['all' => true],
];
Configuration:
Update config/packages/gnuckorg_da_oauth_client.yaml with your OAuth provider details (e.g., client ID, secret, auth URL):
gnuckorg_da_oauth_client:
clients:
my_provider:
type: "oauth2"
client_id: "%env(OAUTH_CLIENT_ID)%"
client_secret: "%env(OAUTH_CLIENT_SECRET)%"
auth_url: "https://provider.com/oauth/authorize"
access_token_url: "https://provider.com/oauth/token"
scope: ["openid", "profile"]
First Use Case: Inject the OAuth client service and authenticate a user:
use Gnuckorg\DaOAuthClientBundle\Client\OAuthClientInterface;
public function __construct(OAuthClientInterface $oauthClient) {
$this->oauthClient = $oauthClient;
}
public function login(Request $request) {
$authUrl = $this->oauthClient->getAuthenticationUrl('my_provider');
// Redirect user to $authUrl
}
public function callback(Request $request) {
$user = $this->oauthClient->getUserFromAccessToken('my_provider', $request->query->get('code'));
// Handle user data (e.g., save to session or database)
}
Routing:
Add routes in config/routes.yaml:
gnuckorg_da_oauth_client_connect:
path: /connect/{provider}
controller: Gnuckorg\DaOAuthClientBundle\Controller\ConnectController::connectAction
gnuckorg_da_oauth_client_callback:
path: /connect/{provider}/callback
controller: Gnuckorg\DaOAuthClientBundle\Controller\ConnectController::callbackAction
Authentication Flow:
$oauthClient->getAuthenticationUrl('provider')./connect/{provider}/callback to exchange code for an access_token.$oauthClient->getUserFromAccessToken('provider', $accessToken).User Data Handling:
User object returned by getUserFromAccessToken to populate your user model:
$userData = $oauthClient->getUserFromAccessToken('my_provider', $accessToken);
$yourUser = new YourUserEntity();
$yourUser->setEmail($userData->getEmail());
$yourUser->setName($userData->getFirstName() . ' ' . $userData->getLastName());
Multi-Provider Support:
gnuckorg_da_oauth_client.yaml and switch between them dynamically:
$provider = $request->get('provider'); // e.g., 'google', 'github'
$authUrl = $this->oauthClient->getAuthenticationUrl($provider);
Token Refresh:
$oauthClient->refreshAccessToken('provider', $refreshToken) to handle expired tokens.Symfony Security:
Integrate with Symfony’s security system by creating a custom UserProvider or Authenticator:
public function loadUserByOAuthToken($token, $provider) {
$userData = $this->oauthClient->getUserFromAccessToken($provider, $token);
return $this->userRepository->findOrCreateByOAuthData($userData);
}
State Parameter:
Always include a state parameter in the auth URL to prevent CSRF:
$state = bin2hex(random_bytes(32));
$request->getSession()->set('oauth_state', $state);
$authUrl = $this->oauthClient->getAuthenticationUrl('my_provider', ['state' => $state]);
Verify the state in the callback to ensure request integrity.
Custom User Data Mapping:
Extend the Gnuckorg\DaOAuthClientBundle\User\User class to map provider-specific fields to your user model:
class CustomUser extends User {
public function getCustomField() {
return $this->get('custom_field_from_provider');
}
}
Logging: Log OAuth events (e.g., token exchange failures) for debugging:
try {
$user = $this->oauthClient->getUserFromAccessToken('provider', $code);
} catch (\Exception $e) {
$this->logger->error('OAuth token exchange failed', ['exception' => $e]);
throw $e;
}
Deprecated Bundle:
league/oauth2-client if critical features are missing.Missing Documentation:
README and inline docs are sparse. Key methods like getUserFromAccessToken lack examples for handling provider-specific responses.State Parameter Handling:
$requestState = $request->query->get('state');
$sessionState = $request->getSession()->get('oauth_state');
if ($requestState !== $sessionState) {
throw new \RuntimeException('Invalid state parameter.');
}
Token Storage:
class UserTokenManager {
public function saveToken(User $user, string $token, string $provider) {
$user->setOAuthToken($token, $provider);
$this->userRepository->save($user);
}
}
Provider-Specific Quirks:
scope or options arrays:
gnuckorg_da_oauth_client:
clients:
google:
options:
display: "popup" # For Google's popup auth
Error Handling:
invalid_grant) may not bubble up predictably. Wrap calls in try-catch blocks:
try {
$user = $this->oauthClient->getUserFromAccessToken('provider', $code);
} catch (\HWI\Bundle\OAuthBundle\OAuth\Exception\AccountNotLinkedException $e) {
// Handle account linking (e.g., redirect to manual registration)
}
Enable HWIOAuthBundle Debugging:
Add to config/packages/dev/gnuckorg_da_oauth_client.yaml:
gnuckorg_da_oauth_client:
debug: true
This logs OAuth requests/responses to var/log/dev.log.
Check Provider Responses:
Symfony Profiler:
composer require hwi/oauth-bundle --dev
Custom User Provider: Override the default user provider to transform OAuth data:
# config/packages/gnuckorg_da_oauth_client.yaml
gnuckorg_da_oauth_client:
user_provider: App\Service\CustomOAuthUserProvider
Implement Gnuckorg\DaOAuthClientBundle\User\UserProviderInterface.
Add New OAuth Providers: Extend the bundle by adding new provider configurations dynamically:
$this->container->get('gnuckorg_da_oauth_client.client_manager')->addClient('custom_provider', [
'type
How can I help you explore Laravel packages today?