friendsofsymfony/oauth-server-bundle
## Getting Started
### Minimal Setup
1. **Installation**:
```bash
composer require friendsofsymfony/oauth-server-bundle
Add to config/bundles.php (Symfony) or AppKernel.php (legacy):
FriendsOfSymfony\OAuthServerBundle\FOSOAuthServerBundle::class => ['all' => true],
Configuration:
Enable the bundle in config/packages/fos_oauth_server.yaml (Symfony 4.4+):
fos_oauth_server:
db_driver: orm # or 'pdo' for PDO-based storage
client_class: %fos_oauth_server.model.client.class%
access_token_class: %fos_oauth_server.model.access_token.class%
refresh_token_class: %fos_oauth_server.model.refresh_token.class%
auth_code_class: %fos_oauth_server.model.auth_code.class%
First Use Case:
Generate a Client:
Use the fos_oauth_server:client:create command:
php bin/console fos:oauth-server:client:create --random --grant-type=password,refresh_token
Note the client_id and client_secret for API calls.
Test OAuth Flow: Use Postman/curl to request a token:
curl -X POST http://your-app/oauth/v2/token \
-d "grant_type=password&client_id=YOUR_CLIENT_ID&client_secret=YOUR_SECRET&username=test&password=test"
config/packages/fos_oauth_server.yaml: Core configuration.src/Entity/ (or Resources/config/doctrine/): Doctrine entities for OAuth models (Client, AccessToken, etc.).Resources/doc/index.md: Official documentation for advanced setups.Dynamic Client Creation:
Extend the ClientManager service to create clients programmatically:
$clientManager = $this->get('fos_oauth_server.client_manager');
$client = $clientManager->createClient();
$client->setRandomId();
$client->addGrantType('password');
$clientManager->updateClient($client);
Client-Specific Logic:
Override ClientManager to inject custom logic (e.g., validate client scopes):
# config/services.yaml
services:
App\Service\CustomClientManager:
decorates: fos_oauth_server.client_manager
arguments: ['@App\Service\CustomClientManager.inner']
Custom Token Storage:
Implement TokenStorageInterface to store tokens in Redis or a custom DB:
class RedisTokenStorage implements TokenStorageInterface {
public function findTokenByToken($token) { /* ... */ }
public function deleteToken($token) { /* ... */ }
}
Register in config/packages/fos_oauth_server.yaml:
fos_oauth_server:
token_storage: App\Service\RedisTokenStorage
Token Validation Middleware:
Use Symfony’s EventSubscriber to validate tokens in controllers:
class OAuthTokenSubscriber implements EventSubscriber {
public static function getSubscribedEvents() {
return [KernelEvents::CONTROLLER => 'onKernelController'];
}
public function onKernelController(ControllerEvent $event) {
$token = $event->getRequest()->headers->get('Authorization');
if (!$this->isValidToken($token)) {
throw new AccessDeniedHttpException();
}
}
}
GrantTypeInterface:
class CustomGrantType implements GrantTypeInterface {
public function getName() { return 'custom'; }
public function validateGrant($grantData, $client, $user) { /* ... */ }
}
Register in config/packages/fos_oauth_server.yaml:
fos_oauth_server:
grants:
- custom
fos_oauth_server:
user_provider: fos_user.user_provider.username_email
Or create a custom provider:
class CustomUserProvider implements UserProviderInterface {
public function loadUserByUsername($username) { /* ... */ }
}
HttpFoundation components via symfony/http-foundation:
use Symfony\Component\HttpFoundation\Request;
$request = Request::createFromGlobals();
$token = $request->headers->get('Authorization');
Validate tokens in Laravel middleware:
class OAuthMiddleware {
public function handle($request, Closure $next) {
$token = $request->bearerToken();
if (!$this->validateToken($token)) {
abort(401);
}
return $next($request);
}
}
league/oauth2-server (actively maintained).config/packages/fos_oauth_server.yaml:
fos_oauth_server:
client_class: App\Entity\CustomClient
access_token_class: App\Entity\CustomAccessToken
make:entity to scaffold custom entities matching the bundle’s interfaces.fos_oauth_server:cleanup:tokens) may fail if storage is misconfigured.
TokenStorageInterface implementation for deleteToken() logic.$schedule->command('fos:oauth-server:cleanup:tokens')->daily();
validateGrant() returns false without throwing an exception.
OAuthServerException for invalid grants:
throw new OAuthServerException('Invalid grant data');
security.yaml to allow OAuth routes:
security:
access_control:
- { path: ^/oauth/v2/token, roles: PUBLIC_ACCESS }
VerifyCsrfToken middleware exclusion for /oauth/v2/token.client_secret in config or client-side code.
.env and fetch via:
$clientSecret = config('services.oauth.client_secret');
debug: true in config/packages/fos_oauth_server.yaml to log OAuth events:
fos_oauth_server:
debug: true
EventSubscriber to log grant data:
class OAuthDebugSubscriber implements EventSubscriber {
public static function getSubscribedEvents() {
return [OAuthEvents::GRANT_VALIDATED => 'onGrantValidated'];
}
public function onGrantValidated(GrantValidatedEvent $event) {
\Log::info('Grant validated', ['grant' => $event->getGrant()->getName(), 'data' => $event->getGrantData()]);
}
}
POST /oauth/v2/token
Headers: Content-Type: application/x-www-form-urlencoded
Body: grant_type=password&client_id=CLIENT_ID&client_secret=SECRET&username=USER&password=PASS
php bin/console doctrine:schema:validate
Recreate if needed:
php bin/console doctrine:schema:update --force
How can I help you explore Laravel packages today?