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

Oauth Bundle Laravel Package

sumocoders/oauth-bundle

A Symfony bundle from SumoCoders that adds OAuth authentication support, helping you integrate OAuth providers and secure your application with minimal configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check first: this is a Symfony bundle, not a Laravel package. There is no service provider, no facade, no config file in config/. If you are in a Laravel codebase, the practical path is to treat this repo as a reference implementation and use laravel/socialite instead — the bundle is essentially a thin Symfony Security wrapper around league/oauth2-client, and Socialite covers the same ground with a fraction of the wiring. Read the rest of this as "how to evaluate/port/borrow from it," plus how you'd use it if you actually are in a Symfony app.

What changed in v1.3.2: one commit, doctrine-bundle upgraded to 3.0. No new providers, no new config keys, no deprecations, no changes to the firewall listener or user-provider contract. It is a dependency bump, not a feature release — but it is a signal: DoctrineBundle 3.0 requires Symfony 6.4+/PHP 8.1+, so the maintainer's CI has almost certainly moved off the Symfony 4/5 era. Open composer.json and check whether doctrine-bundle landed in require or require-dev before assuming your Symfony version story.

Minimal steps in a Symfony app:

  1. composer require sumocoders/oauth-bundle — read composer.json first, and read it carefully. If doctrine-bundle: ^3.0 is under require (not require-dev), Composer will force DoctrineBundle 3.0 into your app, which drags Symfony 6.4+/PHP 8.1 as a floor and conflicts with any app still on DoctrineBundle 2.x. If it is require-dev, it only reflects the package's own test matrix and you can ignore it. This distinction is now the single most important line in the file.
  2. Register SumoCoders\OAuthBundle\SumoCodersOAuthBundle in config/bundles.php (or AppKernel::registerBundles() on legacy).
  3. Add a sumocoders_oauth: block with your client_id, client_secret, scopes, and redirect_uri for each provider (Google, GitHub, etc.).
  4. Wire a firewall that uses the bundle's listener factory, and expose a route for the callback URL you registered with the provider.
  5. Hit the login route, approve at the provider, land back on the callback.

Where to look first, in this order:

  • composer.json — now doubly important. It pins both the league/oauth1-client / league/oauth2-client major version (which determines provider class names and method signatures) and, as of v1.3.2, the DoctrineBundle major. Check require vs require-dev.
  • DependencyInjection/Configuration.php — the authoritative list of config keys. README examples drift; this file does not, and it is unchanged in v1.3.2, so any config you had working on v1.3.1 still works.
  • Resources/config/services.* — service IDs, which you'll need for debug:container and for decoration.
  • Security/Http/ — the firewall listener (the actual redirect/callback dance) and the authentication provider. Untouched by this release.
  • Security/Core/User/ — the user provider interface you'll implement to bridge OAuth data into your own User entity.

First use case: replace a hand-rolled "Login with Google" controller. You get the redirect/state handling and a Security token for free, at the cost of coupling your user model to the bundle's user provider contract.

Implementation Patterns

Custom user provider (the one thing you'll definitely write). The bundle hands you the provider's response (access token + getResourceOwner() data); you decide what a local user looks like. Implement the bundle's user-provider interface and do just-in-time provisioning there:

  • Look up by (provider, provider_user_id), not by email.
  • On miss, create the record, store the provider ID, and leave password null.
  • On hit, optionally refresh profile fields (name, avatar) but never the email without a verification story.
  • Return any Symfony\Component\Security\Core\User\UserInterface; the bundle's own OAuthUser is fine for a prototype, replace it for real apps.

Provider-per-firewall. The cleanest Symfony wiring is one firewall per provider (/auth/google, /auth/github), each with its own listener and user provider. This keeps scopes and redirect URIs unambiguous. A single firewall that switches on a query parameter works but you'll be fighting the security matcher.

Stateless/API variant. If you're using this to mint a token rather than start a session, use a stateless firewall with the OAuth listener and issue your own JWT/session-token in a success handler. Do not rely on the bundle's session token for a SPA — the redirect flow will fight your CSRF setup.

Porting to Laravel (if that's actually the job). The useful extraction is not the bundle, it's the sequence:

  1. Build the provider via league/oauth2-client (new Google(['clientId' => ..., 'clientSecret' => ..., 'redirectUri' => ...])).
  2. getAuthorizationUrl(['state' => $state]), stash state in the session.
  3. Callback: verify state, handle ?error=access_denied before anything else, then getAccessToken('authorization_code', ['code' => $code]).
  4. $provider->getResourceOwner($token) and map to your user model — same (provider, provider_id) keying as above.

That's ~60 lines in a Laravel controller and removes the Symfony coupling entirely. Note the DoctrineBundle bump changes nothing about this port — the league/oauth2-client surface is what you're copying, and it moved.

Testing. Never hit the real provider in tests. Swap the underlying league provider for a stub via container decoration (Symfony) or a bound fake (Laravel), and assert on state mismatch, error= callbacks, and the "existing user" vs "new user" branches of your user provider. Those three cases are where OAuth logins actually break. If you maintain a fork, the v1.3.2 DoctrineBundle bump is a reminder that your CI matrix is now effectively PHP 8.1+/Symfony 6.4+ whether or not you intended that — pin your own dev deps explicitly so a patch release doesn't silently move your test floor.

Gotchas and Tips

  • No Laravel integration and effectively no community. Zero dependents and low stars means no Stack Overflow answers, no blog posts, no issue history to learn from. You are reading the source. Budget for that. A one-PR patch release does not change this.
  • The v1.3.2 dependency bump is the whole release — check it doesn't bite you. If doctrine-bundle: ^3.0 is in require, Composer resolution will fail on apps pinned to DoctrineBundle 2.x / Symfony <6.4, and you'll get an opaque conflict message that looks like the OAuth bundle is incompatible when it's really the ORM layer. If it's in require-dev, nothing in your runtime changes and this release is a no-op for you. Don't skip that check before composer update.
  • Still no new features or deprecations to migrate for. Nothing in Configuration.php, the firewall listener, or the user-provider contract moved between v1.3.1 and v1.3.2. If you had a working integration, this is a safe patch upgrade barring the dependency conflict above. Equally: if you were waiting for a feature, this isn't it.
  • Symfony version friction is now more ambiguous than "it's 4/5-era." The DoctrineBundle 3.0 move implies modern Symfony in the test matrix, but the security YAML in the README may still be written for the old style. Trust Configuration.php and Resources/config/services.* over both the README and any inference from the changelog.
  • Redirect URI must match byte-for-byte. Scheme, host, port, trailing slash, and www. all count. The single most common "invalid_grant" cause. Register both http://localhost and the ported variant during dev.
  • state requires a session. If your app is API-only, has a custom session handler, or your callback is behind a load balancer without sticky sessions, the state check fails intermittently. Verify session persistence on the callback path before blaming the bundle.
  • Don't key users on email. Google returns email_verified: false for some workspace accounts, GitHub email can be private/nulled, and users change emails. Key on the provider's immutable subject ID.
  • Handle ?error= explicitly. Users hit "Cancel" on the consent screen constantly; the callback arrives with error=access_denied and no code. Unhandled, this is a 500 in your logs and a blank page for the user.
  • Scopes may not be what you configured. Some providers return a subset; some require offline access (access_type=offline for Google) to get a refresh token at all. The bundle does not refresh tokens for you — if the access token expires mid-session, you own that.
  • Firewall ordering matters. The OAuth listener must be attached to the right firewall, and the callback path must be reachable unauthenticated. On Symfony 6+, anonymous: true is implicit but the matcher rules still bite; use bin/console debug:firewall <name> to confirm the listener is actually registered.
  • Config drift across versions. Between the Symfony 4/5 and 6+ security rewrites, the same bundle needs different YAML. bin/console debug:config sumocoders_oauth tells you what the current Configuration.php actually accepted — trust that over the README.
  • Debugging tip: set a breakpoint (or dump()) inside the firewall listener's attemptAuthentication/onAuthenticationSuccess. Nine out of ten failures are visible in the exact URL and query params at that point.
  • Extension points worth knowing: the firewall factory (swap the listener), the user provider (swap the mapping), and service decoration on the underlying league client (swap the HTTP layer for logging or a test double). Everything else is closed by design, and v1.3.2 added no new ones.
  • Given the maintenance profile (single small vendor, long release gaps, patch releases that are single dependency bumps), wrap your integration behind your own interface even in Symfony. If the bundle stalls on a Symfony or DoctrineBundle upgrade, you want the swap to be one class, not a rewrite.
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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect