Weave 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

tamtamp/oauth2-server-bundle

Symfony bundle for running an OAuth2 authorization server in your app: it handles grant flows and access token issuing so you can protect APIs without building the protocol yourself. Early-stage project with minimal adoption so far.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check first: tamtamp/oauth2-server-bundle is a Symfony bundle, not a Laravel package. It will not install or boot in a Laravel app — it depends on symfony/framework-bundle, symfony/security-bundle, Doctrine ORM, and the Symfony DI container. If you are working in Laravel, this package is only useful to you in two ways: (a) as a reference for how league/oauth2-server is wired up, and (b) if you also maintain Symfony services. The Laravel-native equivalent is laravel/passport, which wraps the same underlying library (league/oauth2-server).

Where to look first:

  1. The underlying library, not the bundle. Read league/oauth2-server (AuthorizationServer, ResourceServer, GrantType, ClientRepository, AccessTokenRepository, ScopeRepository). Everything the bundle does is glue around that library.
  2. config/packages/*oauth2*server.yaml in a Symfony app — the bundle's configuration tree (authorization_server, resource_server, grants, scopes, persistence) is where the day-to-day behavior lives.
  3. The Doctrine entities (Client, AccessToken, RefreshToken, AuthCode, Scope) — you map these or extend them into your app.

Minimal Symfony setup flow (if you are on Symfony):

composer require tamtamp/oauth2-server-bundle
# register the bundle in config/bundles.php
# generate keypair + encryption key
openssl genrsa -out var/oauth-private.key 2048
openssl rsa -in var/oauth-private.key -pubout -out var/oauth-public.key
php -r "echo base64_encode(random_bytes(32));"   # encryption_key

Then configure the authorization and resource servers, create the persistence entities, run migrations, and wire the OAuth2 firewall endpoints (/token, /authorize) plus a resource-server firewall for your API routes.

First use case: pick the grant that matches your product. For an API consumed by first-party mobile/JS clients, use Authorization Code + PKCE. For service-to-service, use Client Credentials. Do not use the Password grant for anything new — the library deprecates the pattern and it bakes bad UX into your mobile app.

In Laravel terms, the first use case is: Passport::tokensCan([...]) defines scopes, php artisan passport:client creates a client, and the auth:api guard resolves the resource server — the same conceptual objects, different package.

Implementation Patterns

Split your two servers. The bundle distinguishes the authorization server (issues tokens: /token, /authorize) from the resource server (validates tokens on your API). Keep them behind separate Symfony firewalls with separate security configs. This mirrors Passport::actingAs() vs. the auth:api middleware in Laravel — mixing them is how you end up accidentally trusting tokens from your own authorization endpoint for scopes they were never meant to carry.

Grants are toggles. Configure only the grants you actually expose:

  • authorization_code (add PKCE) — third-party or SPA/mobile clients
  • client_credentials — machine-to-machine
  • refresh_token — always pair with authorization_code
  • password — avoid

Scope discipline. Define scopes as configuration, validate them on the ScopeRepository, and enforce them at the resource server (the equivalent of Laravel's ->middleware('scope:orders.read')). Never trust a client-requested scope without intersect-with-config.

Persistence via Doctrine mapping. Use the bundle's entities as mapped superclasses (or reference them directly) and extend your User entity with the user trait / OAuth2UserInterface. Then run migrations. This is the most error-prone part of the setup because Symfony's Doctrine mapping wants explicit #[ORM\Entity] attributes and inheritance config; mismatches show up as silent empty token lookups, not exceptions.

Consent and user resolution are events. The bundle exposes AuthorizationRequestResolveEvent (to render/approve consent and return the user id) and UserResolveEvent (to map the user during password/user resolution). Do consent here — do not try to shoehorn the authorize page into a controller.

Token issuance/validation services. Inject the authorization server service to issue tokens and the resource server to validate Authorization: Bearer … headers. The bundle ships authenticators/guards that handle the HTTP layer for you.

CLI for provisioning. Use the bundle's console commands to create clients and scopes rather than hand-editing the database — the equivalent of php artisan passport:client --client and Passport::tokensCan.

Testing. Hit the /token endpoint with a real client via the bundle's test setup, then assert on the resource-server response. In Laravel, Passport::actingAs($user, ['scope']) is the shortcut you would reach for — the bundle has no comparable ergonomic, so expect to boot the Symfony kernel in tests.

Gotchas and Tips

  • This fork is effectively abandoned. 0 stars, 0 dependents, last release 2022-12-27, and a repo that is a re-namespace of trikoder/oauth2-bundle. Do not adopt it for new work. If you need Symfony OAuth2, use the upstream trikoder/oauth2-bundle (or league/oauth2-server directly). If you need Laravel, use laravel/passport — it tracks league/oauth2-server releases and is maintained.
  • Zero dependents means zero integration testing in the wild. Pin exact versions in composer.json (league/oauth2-server ^8, Symfony 5.x/6.x, PHP 7.4–8.1). Expect breakage on Symfony 7 / PHP 8.3+ — the bundle predates both.
  • Encryption key is for auth codes, not tokens. encryption_key (base64, 32 bytes) protects authorization codes; the RSA keypair signs/validates access tokens. Rotating either invalidates in-flight tokens — plan rotation windows.
  • Opaque vs JWT confusion. By default tokens are opaque and validated by DB lookup or public-key verification depending on your resource-server config. Don't assume you can decode a JWT — if AccessTokenRepository isn't finding tokens, check whether you configured resource-server public key verification or DB lookup.
  • Entity mapping is the #1 source of bugs. Missing #[ORM\Entity], wrong inheritance type, or forgetting accessToken/refreshToken relations yields "invalid_grant" and empty token lists with no stack trace. Verify with a manual SELECT before assuming the grant logic is wrong.
  • Exceptions carry hints. Catch League\OAuth2\Server\Exception\OAuthServerException and log getHint()/getErrorType() — the Symfony profiler does not surface OAuth errors usefully. invalid_client, invalid_grant, invalid_scope map to distinct config problems.
  • Refresh token reuse. If you don't implement rotation (revoke old on use), stolen refresh tokens live until expiry. The library supports rotation; confirm your persistence layer actually deletes the old token.
  • Security headers and CORS. /token and /authorize need CORS for browser clients and must be excluded from session-based CSRF in ways that differ from your normal Symfony firewall. Preflight OPTIONS on /token is a classic missing rule.
  • Never log tokens or Authorization headers, and scrub them from Symfony's request/response logging.
  • Extension points: custom grants (GrantTypeInterface), custom ResponseType, custom scope validation, and listeners on the resolve events. Keep these thin — the library's interfaces are stable; the bundle's DI wiring is not.
  • Migration reality: if you do use this in Symfony, budget to vendor the four or five entity classes and the firewall config into your app rather than relying on the bundle's future releases — it likely won't have any.
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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource