Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Oauth2 Server Bundle Laravel Package

league/oauth2-server-bundle

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Installation**:
   ```bash
   composer require league/oauth2-server-bundle doctrine/doctrine-bundle doctrine/orm

Enable the bundle in config/bundles.php:

return [
    // ...
    League\OAuth2ServerBundle\OAuth2ServerBundle::class => ['all' => true],
];
  1. Database Migration: Run Doctrine migrations to set up the required tables:

    php bin/console doctrine:migrations:diff
    php bin/console doctrine:migrations:migrate
    
  2. First Use Case:

    • Register a Client:
      php bin/console make:oauth2-client --name="MyAppClient" --redirect-uri="https://yourapp.com/callback"
      
    • Test OAuth Flow: Use Postman or cURL to request a token:
      curl -X POST \
        -H "Content-Type: application/x-www-form-urlencoded" \
        -d "grant_type=client_credentials&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET" \
        http://yourapp.test/oauth/token
      
  3. Key Files:

    • config/packages/league_oauth2_server.yaml: Main configuration.
    • src/Entity/: Auto-generated OAuth entities (clients, scopes, etc.).
    • src/Security/: Custom authentication logic (if extending).

Implementation Patterns

Core Workflows

  1. Token Generation:

    • Use the built-in endpoints (/oauth/authorize, /oauth/token) for standard flows (authorization code, implicit, client credentials, etc.).
    • Example: Force a password grant flow by extending the TokenController:
      // src/Controller/OAuthController.php
      use League\OAuth2Server\ResourceServer;
      
      class OAuthController extends AbstractController {
          public function token(ResourceServer $server) {
              $request = Request::createFromGlobals();
              $server->validateAuthenticatedRequest($request);
              // Custom logic (e.g., validate credentials)
              $token = $server->issueAccessToken();
              return new JsonResponse($token->jsonSerialize());
          }
      }
      
  2. Resource Protection:

    • Protect routes with the ResourceServer middleware:
      # config/routes.yaml
      protected_route:
          path: /api/protected
          methods: GET
          controller: App\Controller\ProtectedController::index
          requirements:
              role: ROLE_USER
          defaults:
              _oauth: true  # Adds ResourceServer middleware
      
    • In controller:
      use League\OAuth2Server\ResourceServer;
      
      class ProtectedController {
          public function index(ResourceServer $server) {
              $request = Request::createFromGlobals();
              $server->validateAuthenticatedRequest($request);
              // Access user data via $server->getResourceOwner()
              return new JsonResponse(['data' => 'protected']);
          }
      }
      
  3. Custom Grant Types:

    • Extend the GrantType interface to support custom flows (e.g., JWT bearer):
      use League\OAuth2Server\Grant\GrantTypeInterface;
      
      class CustomGrant implements GrantTypeInterface {
          public function respondToAccessTokenRequest() { /* ... */ }
      }
      
    • Register in config:
      league_oauth2_server:
          grants:
              custom_grant: League\OAuth2ServerBundle\Grant\CustomGrant
      
  4. Scopes and Roles:

    • Define scopes in the database or via YAML:
      league_oauth2_server:
          scopes:
              read: Read access
              write: Write access
      
    • Assign scopes to clients during registration or via migration.
  5. User Authentication:

    • Integrate with Symfony’s security system by extending UserEntity:
      use League\OAuth2Server\Entity\UserEntityInterface;
      
      class AppUser implements UserEntityInterface {
          public function getIdentifier() { /* ... */ }
          public function getEmail() { /* ... */ }
          // Implement other required methods
      }
      
    • Link users to OAuth entities in a migration or via a service.

Integration Tips

  1. Laravel-Specific Adaptations:

    • Use Symfony’s HttpFoundation components (e.g., Request, Response) via Laravel’s bridge:
      use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
      
      $request = SymfonyRequest::createFromGlobals();
      
    • For Laravel’s Auth facade, create a bridge service:
      class OAuthUserProvider implements UserProviderInterface {
          public function retrieveByToken($tokenId, $type) {
              $user = Auth::guard('api')->user();
              return $user ? new AppUser($user) : null;
          }
      }
      
  2. Testing:

    • Use League\OAuth2Server\Tests\TestCases\Traits for unit tests.
    • Mock the ResourceOwnerRepositoryInterface and ClientRepositoryInterface:
      $clientRepo = $this->createMock(ClientRepositoryInterface::class);
      $clientRepo->method('getClientEntity')->willReturn($clientEntity);
      $server = new Server($clientRepo, $accessTokenRepo, $scopeRepo, $privateKey, $encryptionKey);
      
  3. Caching:

    • Cache token validation results (e.g., using Symfony’s cache component):
      league_oauth2_server:
          cache:
              enabled: true
              pool: cache.app
      
  4. Logging:

    • Enable debug logging for OAuth events:
      league_oauth2_server:
          debug: true
      

Gotchas and Tips

Pitfalls

  1. Database Schema Mismatches:

    • Always run migrations after updating the bundle. The auto-generated entities (ClientEntity, AccessTokenEntity, etc.) may change between versions.
    • Fix: Delete and regenerate migrations if schema changes:
      php bin/console doctrine:migrations:diff --complete
      
  2. CSRF Protection:

    • The bundle does not handle CSRF for authorization requests by default. Use Symfony’s csrf_token in forms or add middleware:
      $middleware->add(new \Symfony\Component\HttpKernel\EventListener\CsrfTokenListener());
      
  3. Token Expiry:

    • Tokens expire by default (e.g., 3600 seconds). Customize in config:
      league_oauth2_server:
          access_token_lifetime: 7200  # 2 hours
      
    • Gotcha: Refresh tokens also expire (default: 2592000 seconds). Set to null for infinite lifetime (not recommended for production).
  4. Scope Validation:

    • Scopes are not automatically validated against user roles. Manually check in your resource server logic:
      $scopes = $server->getRequestedScopes();
      if (!in_array('read', $scopes)) {
          throw new \League\OAuth2Server\Exception\OAuthServerException(
              'insufficient_scope',
              'The requested scope is invalid.',
              \League\OAuth2Server\ResponseTypes\AccessTokenResponse::class
          );
      }
      
  5. Client Secret Handling:

    • Avoid hardcoding secrets in config. Use environment variables or Symfony’s parameter_bag:
      # config/packages/league_oauth2_server.yaml
      league_oauth2_server:
          private_key: '%env(OAUTH_PRIVATE_KEY)%'
          encryption_key: '%env(OAUTH_ENCRYPTION_KEY)%'
      
  6. CORS Issues:

    • Ensure your OAuth endpoints (/oauth/authorize, /oauth/token) are included in CORS allowed origins:
      # config/packages/nelmio_cors.yaml
      nelmio_cors:
          defaults:
              allow_origins: ['%env(APP_ALLOWED_ORIGINS)%']
              allow_methods: ['POST', 'OPTIONS']
              allow_headers: ['Authorization', 'Content-Type']
              expose_headers: ['Authorization']
          paths:
              '^/oauth/':
                  allow_origins: ['*']  # Adjust for production
      

Debugging Tips

  1. Enable Debug Mode:

    league_oauth2_server:
        debug: true
    
    • Logs detailed errors to var/log/dev.log.
  2. Token Validation Errors:

    • Check the error and error_description fields in failed token requests. Common errors:
      • invalid_client: Client ID/secret mismatch.
      • invalid_grant: Authorization code or refresh token expired/invalid.
      • unsupported_grant_type: Grant type not enabled for the client.
  3. Database Debugging:

    • Use Doctrine’s query logging to inspect SQL:
      doctrine:
          dbal:
              logging: true
              profiling: true
      
  4. Middleware Order:

    • Ensure ResourceServerMiddleware runs after FirewallMiddleware in your security config:
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor