matt-czerner/oauth2-bundle
A Symfony bundle for adding OAuth2 authentication to your application, with configuration for clients, providers, and token handling. Simplifies wiring OAuth2 flows into Symfony's security layer so you can secure routes and authenticate users with minimal boilerplate.
First, the framing problem: this is a Symfony bundle, not a Laravel package. There is no ServiceProvider, no config/oauth2.php to publish, no package auto-discovery. composer require matt-czerner/oauth2-bundle in a Laravel app will install code you cannot boot, because bundle registration happens in config/bundles.php inside a Symfony kernel that doesn't exist in your app. Treat this as "a service you might run alongside Laravel," not a dependency you drop in.
If you are actually in a Symfony codebase:
composer require matt-czerner/oauth2-bundleconfig/bundles.phpDependencyInjection/Configuration.php and DependencyInjection/*Extension.php first — that is the only authoritative list of what is configurable and which services get aliased.composer.json of the bundle for the pinned league/oauth2-server version before writing anything; the repository interfaces and grant APIs differ meaningfully between major versions.First use case: a client-credentials grant for machine-to-machine auth is the shortest path to a working token endpoint, because it needs no user table, no consent screen, and no login flow.
For a Laravel developer the realistic first move is: stand this up as a small Symfony authorization server (or skip the bundle and use league/oauth2-server directly), and have Laravel act purely as a resource server.
Split the two roles explicitly. An OAuth2 deployment has an authorization server (issues tokens) and a resource server (validates them). They are different middleware, different key material, different failure modes. Most bad integrations come from blurring them.
Pattern A — sidecar authorization server (recommended for Laravel).
POST /token with client credentials over the private network.Pattern B — port it to a Laravel service provider. Skip the bundle entirely, composer require league/oauth2-server, and wire the grant types yourself in a provider. You will still need to implement ClientRepositoryInterface, AccessTokenRepositoryInterface, ScopeRepositoryInterface, and friends — this time against Eloquent.
Pattern C — use Laravel Passport. Passport is league/oauth2-server with Eloquent models, a TokenGuard, Artisan commands, and passport:keys` already written. If your only requirement is "issue tokens to our own clients," this bundle gives you nothing Passport doesn't, and costs you a second framework.
Middleware translation. Where Symfony uses a security firewall plus an authenticator to extract the bearer token and populate a token/user, Laravel expects a middleware plus a custom guard (Auth::viaRequest) or a simple Bearer check that resolves scopes into gate abilities. Map scopes to Laravel gates/policies early — retrofitting authorization onto an already-issued token is painful.
Scopes as the contract. Define the scope vocabulary once, put it in config, and use the same strings on both sides. Scope strings silently drifting between issuer and consumer is the single most common production bug in these setups.
Doctrine assumption. A Symfony OAuth bundle of this shape almost certainly ships Doctrine entities and repository implementations. Laravel is Eloquent. Reusing the bundle's persistence layer from Laravel is not viable; you would be reimplementing every repository interface anyway.
Symfony Security and EventDispatcher coupling. The bundle will expect Symfony's UserProvider, firewall, and event dispatcher contracts. There is no adapter layer. Anything touching authenticated users or token events has to be rebuilt for Laravel.
Zero stars, zero dependents, single release (2024-07-30). No Stack Overflow corpus, no blog posts, no third-party bug reports, no security review. Budget time to read the source. Pin the exact version in composer.json and treat any upgrade as a manual diff review.
Verify the league/oauth2-server version. Major versions changed the repository interface signatures and the key/encryption configuration. Copy-pasting a tutorial written against a different major version produces type errors that look like bundle bugs.
Resource server validation details. Decide JWT verification vs. opaque-token introspection up front. JWT means key distribution and clock-skew tolerance (leeway); introspection means a network hop on every request and a cache you must invalidate on revocation.
Key and secret handling. Private keys and client secrets go in env vars or a secrets manager, never the repo. Confirm the bundle hashes client secrets rather than storing them plaintext — read that repository implementation specifically. Set asymmetric key file permissions; Symfony will happily start with a world-readable key.
Token lifetime and rotation. Short access tokens, rotating refresh tokens, and an actual revocation path. Test that a revoked token is rejected by the resource server within your acceptable window, not just by the issuer.
Extension points. Prefer implementing the bundle's repository interfaces over patching vendor code, and use service decoration or a compiler pass to override a single service. Anything you override is a maintenance liability on a package with no upstream activity — keep the overrides in one directory and document why each exists.
Testing. Generate a throwaway keypair for the test suite and issue real tokens against it; mocking the token endpoint hides serialization, audience, and expiry bugs. Seed clients via fixtures, not production data.
How can I help you explore Laravel packages today?