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

Knp Oauth Bundle Laravel Package

knplabs/knp-oauth-bundle

KnpOAuthBundle integrates OAuth authentication into Symfony applications, providing services and configuration for connecting to OAuth providers. It simplifies wiring OAuth clients, handling access tokens, and authenticating users through third-party services.

View on GitHub
Deep Wiki
Context7

Getting Started

Read the archive banner before anything else. This is a Symfony bundle, not a Laravel package, it is archived, and its own description redirects you to hwi/oauth-bundle. There is no Laravel service provider, no guard driver, no Socialite adapter, and no container bridge. If you are on Laravel, the correct day-one action is to close this tab and composer require laravel/socialite. The only legitimate reason to be reading further is that you have inherited a Symfony 2.x application that already runs this bundle and you need to change or replace it.

If you inherited a legacy Symfony install, three files are the entire wiring:

// app/AppKernel.php
$bundles = [
    new Knp\Bundle\OAuthBundle\KnpOAuthBundle(),
];
# app/config/config.yml
knp_oauth:
    oauth:
        resource_owners:
            facebook:
                type: facebook
                client_id: "%facebook_app_id%"
                client_secret: "%facebook_app_secret%"
                scope: "email"
            google:
                type: google
                client_id: "%google_client_id%"
                client_secret: "%google_client_secret%"
                scope: "email profile"
# app/config/security.yml
firewalls:
    login:
        pattern: ^/login
        anonymous: true
        oauth:
            resource_owners:
                facebook: /login/check-facebook
                google:   /login/check-google
            login_path: /login
            failure_path: /login
            oauth_user_provider:
                service: app.oauth_user_provider

Where to look first, in order:

  • Security/Core/User/OAuthAwareUserProviderInterface.php — one method, loadUserByOAuthUserResponse(). This is the whole integration contract for your application code. Everything else is bundle plumbing you configure rather than write.
  • Security/Http/ — the authentication listener and factory. This is where the check-* path is matched and the firewall is entered; read it when a login hangs or redirects in a loop.
  • Resources/config/ — the canonical knp_oauth.* service IDs. These are your extension points for decoration and replacement.
  • The Connect controller and its template (KnpOAuthBundle:Connect:connect) — the "Log in with X" landing page. Import the bundle routing or copy the template.

First use case: a "Log in with Google" button on a Symfony 2 app, mapping the remote identity to a local User entity by email via find-or-create. Configure one resource owner, one firewall oauth block, one user provider implementing the interface, and call $response->getEmail(). That path is well-trodden. Anything involving token refresh, account linking, or provider-specific scopes is not, and is where you will spend the time.

Implementation Patterns

User provider as the only real application code. Register a service implementing OAuthAwareUserProviderInterface and keep it thin — resolve the remote identity to a local entity, nothing more:

class OAuthUserProvider implements OAuthAwareUserProviderInterface
{
    public function loadUserByOAuthUserResponse(UserResponseInterface $response)
    {
        $email = $response->getEmail();
        if (!$email) {
            throw new AccountNotLinkedException('Provider returned no email');
        }

        $user = $this->userRepository->findOneBy(['email' => $email]);
        if (!$user) {
            $user = $this->userRepository->createFromOAuth($response);
        }

        return $user;
    }
}

Then a second listener or JWTAuthenticationSuccessHandler-style success handler does the actual Symfony token issuance. Keep those concerns separate; mixing them is how these integrations rot.

Resource owner configuration is declarative — prefer it over code. Each entry under resource_owners gets a type, client_id, client_secret, scope, and optional paths overrides for endpoints. For any provider the bundle recognizes, config alone is enough. Only extend AbstractResourceOwner for providers that don't exist, and expect to hardcode the endpoints because the bundle ships an old API surface.

Firewall-per-path, not firewall-per-provider. A single oauth firewall with multiple resource_owners entries mapping to distinct check-* paths is the canonical pattern. Adding a second firewall for a new provider is a common over-engineering that produces ordering bugs.

Decorate the bundled service to fix behavior without forking. Because the resource owners live behind stable service IDs, a compiler pass or a service definition with decorates: knp_oauth.resource_owner.facebook lets you patch a broken endpoint or add a missing field without editing vendor code. This is the single most valuable pattern for keeping a legacy install alive: a thin, documented decoration layer that your team owns is far easier to migrate later than an in-place vendor edit nobody remembers.

Use the connect flow deliberately. The bundle's connect controller is a good starting point for a "manage linked accounts" screen — it lists configured providers and renders buttons. Copy the template into your app, don't reference it from the vendor path, so the migration to HWIOAuthBundle or a custom league/oauth2-client authenticator has no template surprises.

Test the callback, not the login. Unit-testing the user provider is cheap and worthwhile (pass a mocked UserResponseInterface, assert find-or-create behavior, assert the no-email path throws). The OAuth round-trip itself should be covered by one integration test per provider that stubs the token endpoint and asserts the redirect URI, state handling, and failure redirect. Providers change their APIs; a test that pins your endpoint configuration is the only thing that will tell you when.

Integration tips for a migration path. Introduce a single SocialLoginService interface in your application, implement it behind the bundle's user provider, and have controllers depend only on your interface. When you replace the bundle with HWIOAuthBundle or league/oauth2-client, the controllers don't move.

Gotchas and Tips

It will not install. This is pinned to Symfony 2.x-era component APIs and predates PHP 7.x conventions in places. On any modern Composer setup it is a resolution failure, not a runtime bug you can work around. Plan for a real integration, not a composer require.

Do not bridge it into Laravel. A Symfony bundle expects the Symfony HTTP kernel, security firewall, event dispatcher, and bundle config model. Any Laravel shim would own OAuth state validation, token exchange, and account mapping itself — at which point the bundle contributes nothing but coupling and a second auth code path. Use laravel/socialite.

Providers have drifted, and the bundle has not. Facebook's Graph API, Google's userinfo endpoint, and GitHub's email visibility have all changed since this code was written. getEmail() returning null is now common — for Facebook when the user hasn't granted email, and for GitHub when the primary email is private. Treat a null email as a first-class case, not an error branch, and show a "confirm your email" step rather than silently failing.

Never link accounts solely on an unverified email. The find-or-create-by-email pattern is convenient and is what the docs imply, but it means anyone who controls an account at any configured provider with a matching email inherits the local account. Either require the provider to assert email_verified (available in Google's response) or implement an explicit "link this account" confirmation flow. This is the single highest-severity thing you can get wrong here, and it is a bug in your provider, not the bundle.

Redirect URI must match byte-for-byte. The bundle's check-* route is what you register with the provider. Trailing slashes, http vs https, and the app's configured base URL all break the callback, and the failure surfaces as a generic provider error page rather than a Symfony exception. Verify the exact URI in the provider console before debugging anything else.

Firewall ordering and the check-* route. The check path is served by the listener inside the firewall, so the request must actually enter it. A more specific firewall pattern registered earlier will shadow it; a security: false area will bypass it entirely. If login redirects but never returns, this is almost always the cause.

anonymous: true vs ~. The old YAML syntax varies by Symfony version and the bundle's docs assume 2.0/2.1-era config. If the config parses but the firewall isn't active, check that security.yml keys match your actual Symfony version — the bundle cannot validate a config format it predates.

Debug at the listener, not the provider. When a login stalls, add logging in Security/Http/ around token exchange and user provider resolution. Provider-side errors are swallowed into a redirect to failure_path, and the underlying exception is easy to lose. Log the UserResponseInterface payload before your user provider runs — this is where you'll discover the email is null, a scope wasn't granted, or the token endpoint returned an error.

Extension points you actually have: service decoration of knp_oauth.resource_owner.*, a custom OAuthAwareUserProviderInterface, the connect controller/template, and firewall configuration. There is no supported hook for token refresh, token storage, or state handling — those are inside the listener. If your requirement touches any of those, that is your signal to migrate rather than extend.

No security patches. Ever. There are zero dependents and no maintainer. If your organization runs any dependency policy, SOC 2 review, or security questionnaire, this dependency is an exception to document. Budget the replacement as a ticket, not a background hope; provider API drift has a way of forcing the migration on someone else's timeline.

When you do migrate, map the surfaces: user provider → hwi/oauth-bundle's OAuthAwareUserProviderInterface (a similar shape, so the port is small), resource owner config → the new bundle's resource_owners YAML, and your decoration layer → the new bundle's extension points or an explicit HTTP client. Keeping that mapping in a doc while the legacy code is fresh is worth more than the code you're deleting.

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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin