aescarcha/oauth
Symfony OAuth server bundle integrating FOSOAuthServer with FOSUser, FOSRest, JMS Serializer, and NelmioApiDoc. Provides routes and configuration to expose JSON-based API authentication and documentation.
Installation Run these commands in order:
composer require aescarcha/oauth "~1"
composer require friendsofsymfony/rest-bundle jms/serializer-bundle nelmio/api-doc-bundle friendsofsymfony/user-bundle aescarcha/user-bundle friendsofsymfony/oauth-server-bundle
Enable Bundles
Add to app/AppKernel.php:
new Aescarcha\OauthServerBundle\AescarchaOauthServerBundle(),
Configure Database
Run migrations for OAuth tables (check src/Aescarcha/OauthServerBundle/Resources/doc/index.md for specifics).
First OAuth Flow
Use the built-in /oauth/v2/auth endpoint to test token generation:
curl -X POST -d "grant_type=password&client_id=your_client_id&client_secret=your_secret&username=user&password=pass" http://your-app/oauth/v2/token
Verify API Docs
Access /api/doc (NelmioApiDocBundle) to explore OAuth endpoints interactively.
Client Registration
Aescarcha\OauthServerBundle\Entity\Client to manage OAuth clients.$client = new Client();
$client->setRandomId(true);
$client->setRedirectUris(['https://yourapp.com/callback']);
$em->persist($client);
$em->flush();
Token Management
Aescarcha\OauthServerBundle\Security\Token\OAuthToken:
$token = $this->get('oauth.server')->getTokenStorage()->createAccessToken($client, $user, $scope);
Resource Server Integration
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
/**
* @Security("is_granted('IS_AUTHENTICATED_FULLY')")
*/
public function secureAction()
{
// ...
}
Custom Scopes
Aescarcha\OauthServerBundle\Entity\Scope for granular permissions:
$scope = new Scope();
$scope->setName('custom:admin');
$scope->setDescription('Admin access');
Refresh Tokens
Aescarcha\OauthServerBundle\Security\Token\RefreshToken:
$refreshToken = $this->get('oauth.server')->getTokenStorage()->createRefreshToken($client, $user);
FOS\UserBundle\Model\User via Aescarcha\UserBundle./api/doc#/OAuth2/token_post).OAuthServer in PHPUnit:
$this->container->set('oauth.server', $this->createMock(OAuthServer::class));
Bundle Dependencies
aescarcha/user-bundle is in dev-master; pin versions to avoid breaking changes:
composer require aescarcha/user-bundle:dev-master@dev
composer why-not aescarcha/user-bundle to debug dependency conflicts.Token Storage
doctrine:orm) may not persist tokens if not configured. Ensure:
# config.yml
aescarcha_oauth:
storage: doctrine
CORS Issues
friendsofsymfony/rest-bundle must be configured for OAuth callbacks:
fos_rest:
format_list:
json: true
param_format: json
Scope Validation
$client->setAllowedScopes(['read', 'write']);
Enable OAuth Logging
Add to config.yml:
aescarcha_oauth:
debug: true
Logs appear in var/log/dev.log.
Token Debugging Dump token data:
$token = $this->get('oauth.server')->getTokenStorage()->findAccessToken($tokenValue);
var_dump($token->getUser(), $token->getScopes());
Common Errors
Invalid grant_type: Ensure grant_type matches the endpoint (e.g., password, authorization_code).Client not found: Verify client_id and client_secret in the database.User not found: Confirm FOS\UserBundle user provider is linked to OAuth.Custom Grant Types
Extend Aescarcha\OauthServerBundle\Security\Token\GrantType\GrantTypeInterface:
class CustomGrantType implements GrantTypeInterface {
public function getName() { return 'custom'; }
public function validate(array $params) { /* ... */ }
}
Register in services.yml:
services:
aescarcha_oauth.grant_type.custom:
class: AppBundle\Security\Token\CustomGrantType
tags:
- { name: oauth.grant_type }
Override Token Storage Bind a custom storage service:
services:
oauth.token_storage:
class: AppBundle\Security\Token\CustomTokenStorage
arguments: ['@doctrine.orm.entity_manager']
API Response Customization
Override Aescarcha\OauthServerBundle\EventListener\TokenResponseListener to modify token responses:
public function onTokenResponse(GetResponseEvent $event) {
$response = $event->getResponse();
$response->headers->set('X-Custom-Header', 'value');
}
How can I help you explore Laravel packages today?