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

Oauth Bundle Laravel Package

beshkenadze/oauth-bundle

Symfony2 bundle for OAuth user authentication (fork of KnpOAuthBundle). Adds OAuth login support for multiple providers, with documentation in Resources/doc and MIT license.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require beshkenadze/oauth-bundle
    

    Enable the bundle in config/bundles.php:

    return [
        // ...
        HWI\OAuthBundle\HWIOAuthBundle::class => ['all' => true],
    ];
    
  2. Configure Providers: Edit config/packages/hwi_oauth.yaml (or create it) to define supported OAuth providers (e.g., Google, Facebook):

    hwi_oauth:
        connect:
            account_connector: your_app.connector.my_oauth
            # List of supported providers
            providers:
                google:
                    type:                google
                    client_id:          "YOUR_CLIENT_ID"
                    client_secret:      "YOUR_CLIENT_SECRET"
                    scope:              "email profile"
                facebook:
                    type:                facebook
                    client_id:          "YOUR_APP_ID"
                    client_secret:      "YOUR_APP_SECRET"
    
  3. First Use Case: Add OAuth login buttons to a template (e.g., templates/security/login.html.twig):

    <a href="{{ path('hwi_oauth_connect', {'service': 'google'}) }}" class="btn btn-google">
        Login with Google
    </a>
    <a href="{{ path('hwi_oauth_connect', {'service': 'facebook'}) }}" class="btn btn-facebook">
        Login with Facebook
    </a>
    
  4. Verify Routes: Check php bin/console debug:router | grep hwi_oauth to confirm routes like:

    • hwi_oauth_connect_<provider> (e.g., hwi_oauth_connect_google)
    • hwi_oauth_check_<provider>
    • hwi_oauth_connect

Implementation Patterns

Workflows

  1. User Authentication Flow:

    • Redirect user to provider via hwi_oauth_connect_<provider>.
    • Provider redirects back to hwi_oauth_check_<provider> with an authorization code.
    • Bundle exchanges code for an access token and fetches user data.
    • Custom account_connector (see below) maps provider data to your user entity.
  2. Account Connector: Implement a service to link OAuth data to your user model (e.g., src/Service/MyOAuthConnector):

    namespace App\Service;
    
    use HWI\Bundle\OAuthBundle\OAuth\Response\UserResponseInterface;
    use HWI\Bundle\OAuthBundle\Security\Core\User\OAuthUserProvider;
    use Symfony\Component\Security\Core\User\UserInterface;
    
    class MyOAuthConnector implements AccountConnectorInterface
    {
        public function connect(UserResponseInterface $response, UserInterface $user = null)
        {
            // Example: Update user's email/name from $response->getEmail()
            $user->setEmail($response->getEmail());
            $user->setFirstName($response->getFirstName());
            $user->addRole('ROLE_OAUTH');
            return $user;
        }
    }
    

    Register it in services.yaml:

    services:
        your_app.connector.my_oauth:
            class: App\Service\MyOAuthConnector
            tags:
                - { name: hwi_oauth.account_connector, connector: account_connector }
    
  3. Post-Auth Logic: Use Symfony’s security.event.authentication_success event to trigger actions after OAuth login:

    // src/EventListener/OAuthLoginListener.php
    public function onAuthenticationSuccess(AuthenticationEvents $events)
    {
        $event = $events->getAuthenticationEvent();
        if ($event->getAuthenticationToken()->getUser() instanceof OAuthUser) {
            // Custom logic (e.g., log activity, redirect)
        }
    }
    

    Register the listener in services.yaml:

    services:
        App\EventListener\OAuthLoginListener:
            tags:
                - { name: kernel.event_listener, event: security.authentication.success, method: onAuthenticationSuccess }
    

Integration Tips

  1. Custom User Provider: Extend OAuthUserProvider to fetch users from your database:

    use HWI\Bundle\OAuthBundle\Security\Core\User\OAuthUserProvider as BaseOAuthUserProvider;
    
    class CustomOAuthUserProvider extends BaseOAuthUserProvider
    {
        public function loadUserByOAuthUserResponse(UserResponseInterface $response)
        {
            $username = $response->getEmail();
            $user = $this->userManager->findUserBy(['email' => $username]);
    
            if (!$user) {
                $user = $this->userManager->createUser([
                    'email' => $username,
                    'roles' => ['ROLE_USER'],
                ]);
            }
    
            return $user;
        }
    }
    

    Configure in security.yaml:

    security:
        providers:
            oauth_user_provider:
                id: App\Security\CustomOAuthUserProvider
    
  2. Provider-Specific Scopes: Dynamically set scopes per provider in the connector:

    public function connect(UserResponseInterface $response, UserInterface $user = null)
    {
        if ($response->getProviderName() === 'google') {
            $user->addRole('ROLE_GOOGLE_USER');
        }
        return $user;
    }
    
  3. CSRF Protection: Disable CSRF for OAuth routes if using tokens (e.g., in config/packages/security.yaml):

    security:
        access_control:
            - { path: ^/connect/, roles: PUBLIC_ACCESS }
    
  4. Testing: Use HWI\Bundle\OAuthBundle\Tests\Mock\MockHttpFoundation to simulate OAuth responses in PHPUnit:

    $mockResponse = new MockHttpFoundation($this->getMockResponse());
    $this->client->getContainer()->set('request', $mockResponse);
    

Gotchas and Tips

Pitfalls

  1. Token Expiry:

    • OAuth tokens expire. Handle HWI\Bundle\OAuthBundle\Exception\TokenExpiredException in your connector:
      try {
          $response = $this->oauth->performStep();
      } catch (TokenExpiredException $e) {
          // Refresh token or re-authenticate
          return $this->redirectToAuthPage();
      }
      
  2. Missing User Fields:

    • Some providers (e.g., GitHub) return minimal data by default. Request additional scopes in hwi_oauth.yaml:
      scope: "user:email,read:org"
      
  3. Circular Redirects:

    • If using Symfony’s firewall, ensure hwi_oauth_connect routes are accessible anonymously:
      security:
          access_control:
              - { path: ^/login, roles: PUBLIC_ACCESS }
              - { path: ^/connect, roles: PUBLIC_ACCESS }
      
  4. Database Locks:

    • Concurrent OAuth logins may cause race conditions when creating users. Use transactions:
      $entityManager->beginTransaction();
      try {
          $user = $entityManager->getRepository(User::class)->findOneBy(['email' => $email]);
          if (!$user) {
              $user = new User();
              $user->setEmail($email);
              $entityManager->persist($user);
          }
          $entityManager->commit();
      } catch (\Exception $e) {
          $entityManager->rollback();
          throw $e;
      }
      
  5. Provider-Specific Quirks:

    • Google: Requires openid scope for basic profile data.
    • Facebook: May return null for optional fields (e.g., phone). Handle gracefully:
      $phone = $response->getPhone() ?: 'N/A';
      

Debugging

  1. Enable Debugging: Set debug: true in hwi_oauth.yaml to log OAuth responses:

    hwi_oauth:
        debug: true
    

    Check logs at var/log/dev.log for raw provider responses.

  2. Common Errors:

    • InvalidArgumentException: Missing client_id/client_secret in config.
    • RuntimeException: Provider type not registered (e.g., type: google requires hwi_oauth.resource_owners.google).
    • ClientException: Invalid redirect URI. Ensure it matches the provider’s registered callback URL.
  3. Provider-Specific Debugging:


Extension Points

  1. Custom Providers: Add support for unsupported providers by extending HWI\Bundle\OAuthBundle\OAuth\ResourceOwner\GenericResourceOwner:
    namespace App\OAuth;
    
    use HWI\Bundle\OAuthBundle\OAuth\ResourceOwner\GenericResourceOwner;
    
    class CustomProvider extends GenericResourceOwner
    {
    
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.
bugban/symfony
beyonder-capi/workflow-extensions-bundle
beyonder-capi/job-queue-bundle
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin