Installation
composer require cleverage/oauth-api-bundle
Add to config/bundles.php:
return [
// ...
Cleverage\OAuthApiBundle\CleverageOAuthApiBundle::class => ['all' => true],
];
Configuration Publish the default config:
php bin/console cleverage:oauth-api:install
Update config/packages/cleverage_oauth_api.yaml with your OAuth provider details (e.g., client ID, secret, token URL).
First Use Case: Fetching OAuth Tokens
Inject the OAuthApiClient service and authenticate:
use Cleverage\OAuthApiBundle\Client\OAuthApiClient;
public function __construct(private OAuthApiClient $oauthClient) {}
public function getAccessToken()
{
$token = $this->oauthClient->getAccessToken(
'client_credentials', // grant type
['scope' => 'read write']
);
return $token->getToken();
}
Token Management
getAccessToken() with a refresh token:
$token = $this->oauthClient->getAccessToken(
'refresh_token',
['refresh_token' => $storedRefreshToken]
);
security.token_storage or a custom service to persist tokens (e.g., in the database or cache).API Requests
$response = $this->oauthClient->request(
'GET',
'https://api.example.com/data',
['headers' => ['Authorization' => 'Bearer ' . $token]]
);
429 Too Many Requests by implementing exponential backoff in your service layer.Event-Driven Extensions
oauth_api.token.refresh events to automate token refreshes:
// src/EventListener/OAuthTokenListener.php
public function onTokenRefresh(TokenRefreshEvent $event) {
$event->setToken($this->generateNewToken());
}
Register in services.yaml:
services:
App\EventListener\OAuthTokenListener:
tags:
- { name: kernel.event_listener, event: oauth_api.token.refresh }
Provider-Specific Configs
config/packages/dev/cleverage_oauth_api.yaml):
cleverage_oauth_api:
providers:
google:
client_id: "%env(GOOGLE_CLIENT_ID_DEV)%"
client_secret: "%env(GOOGLE_CLIENT_SECRET_DEV)%"
Token Expiry Handling
OAuthApiClient to auto-refresh tokens:
class AutoRefreshOAuthClient implements OAuthApiClientInterface {
public function request(string $method, string $url, array $options = []): ResponseInterface {
if ($this->isTokenExpired()) {
$this->refreshToken();
}
return $this->decorated->request($method, $url, $options);
}
}
Provider-Specific Quirks
league/oauth2-client alongside this bundle.Cleverage\OAuthApiBundle\Client\OAuthApiClient to support non-standard grants (e.g., urn:ietf:params:oauth:grant-type:saml2-bearer).Configuration Overrides
cleverage_oauth_api.yaml may not reflect without clearing the cache:
php bin/console cache:clear
Debugging Token Issues
config/packages/dev/cleverage_oauth_api.yaml:
cleverage_oauth_api:
debug: true
oauth_api channel errors (e.g., monolog configuration).Testing
vcr or mockery to record/stub OAuth responses:
$mockClient = Mockery::mock(OAuthApiClient::class);
$mockClient->shouldReceive('getAccessToken')
->andReturn(new Token('mock_token', new \DateTime('+1 hour')));
Performance
Redis or APCu with a short TTL (e.g., 5 minutes before expiry):
$cache = $container->get('cache.app');
$token = $cache->get('oauth_token', function() {
return $this->oauthClient->getAccessToken('client_credentials');
});
Security
%env() or a secrets manager (e.g., symfony/secret).Extending Functionality
Cleverage\OAuthApiBundle\Provider\AbstractProvider for unsupported providers.$this->oauthClient->addInterceptor(function (RequestInterface $request) {
$request->setHeader('X-Custom-Header', 'value');
});
How can I help you explore Laravel packages today?