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

Google Oauth2 Laravel Package

defineweb/google-oauth2

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require defineweb/google-oauth2
    

    Add the bundle to config/bundles.php (Symfony) or register the service provider in config/app.php (Laravel).

  2. Configuration Publish the config file:

    php artisan vendor:publish --provider="Defineweb\GoogleOauth2Bundle\GoogleOauth2ServiceProvider"
    

    Update .env with your Google OAuth2 credentials:

    GOOGLE_OAUTH2_CLIENT_ID=your_client_id
    GOOGLE_OAUTH2_CLIENT_SECRET=your_client_secret
    GOOGLE_OAUTH2_REDIRECT_URI=http://your-app.test/login/google/callback
    
  3. First Use Case: Login Route Add routes in routes/web.php:

    Route::get('/login/google', [GoogleOauth2Controller::class, 'redirectToGoogle'])->name('google.login');
    Route::get('/login/google/callback', [GoogleOauth2Controller::class, 'handleGoogleCallback']);
    
  4. Basic Controller Usage

    use Defineweb\GoogleOauth2Bundle\GoogleOauth2;
    
    public function redirectToGoogle(GoogleOauth2 $googleOauth2)
    {
        return $googleOauth2->redirect();
    }
    
    public function handleGoogleCallback(GoogleOauth2 $googleOauth2)
    {
        $user = $googleOauth2->getUser();
        // Handle user data (e.g., create/update user in DB)
        auth()->login($user);
        return redirect()->intended('/dashboard');
    }
    

Implementation Patterns

Workflows

  1. Authentication Flow

    • Redirect to Google: Use $googleOauth2->redirect() to initiate OAuth flow.
    • Callback Handling: After Google redirects back, call $googleOauth2->getUser() to fetch user data (e.g., email, name, profile pic).
    • User Mapping: Map Google user data to your Laravel User model (e.g., via findOrCreate or custom logic).
  2. User Data Access The getUser() method returns an array like:

    [
        'id' => '123456789',
        'email' => 'user@example.com',
        'name' => 'John Doe',
        'picture' => 'https://.../photo.jpg',
        // Additional Google-provided fields
    ]
    

    Extend this with custom claims by configuring scopes in .env:

    GOOGLE_OAUTH2_SCOPES="email profile https://www.googleapis.com/auth/userinfo.profile"
    
  3. Integration with Laravel Auth

    • Use Auth::login() or auth()->login() to authenticate the user after fetching data.
    • Example:
      $userData = $googleOauth2->getUser();
      $user = User::firstOrCreate(
          ['email' => $userData['email']],
          [
              'name' => $userData['name'],
              'google_id' => $userData['id'],
              'avatar' => $userData['picture']
          ]
      );
      auth()->login($user);
      
  4. Scopes and Permissions

    • Define required scopes in .env (e.g., email, profile, openid).
    • Example for advanced permissions:
      GOOGLE_OAUTH2_SCOPES="https://www.googleapis.com/auth/calendar.readonly"
      
  5. Error Handling

    • Wrap OAuth calls in try-catch blocks to handle exceptions (e.g., invalid credentials, network issues).
    • Example:
      try {
          $user = $googleOauth2->getUser();
      } catch (\Exception $e) {
          \Log::error('Google OAuth error: ' . $e->getMessage());
          return redirect()->route('login')->with('error', 'Google login failed.');
      }
      

Gotchas and Tips

Pitfalls

  1. Redirect URI Mismatch

    • Ensure GOOGLE_OAUTH2_REDIRECT_URI in .env exactly matches the URI registered in Google Cloud Console.
    • Fix: Double-check the trailing slash and HTTPS/HTTP consistency.
  2. Missing Scopes

    • If getUser() returns incomplete data (e.g., no picture), verify scopes in .env include profile.
    • Fix: Add https://www.googleapis.com/auth/userinfo.profile to GOOGLE_OAUTH2_SCOPES.
  3. State Parameter Issues

    • The package may not handle CSRF state parameters by default. If using Symfony’s security component, manually add state validation.
    • Fix: Extend the controller to validate the state:
      public function handleGoogleCallback(Request $request, GoogleOauth2 $googleOauth2)
      {
          if (!hash_equals($request->session()->get('oauth_state'), $request->query('state'))) {
              throw new \RuntimeException('State mismatch');
          }
          // Proceed with login...
      }
      
  4. Token Expiry

    • Refresh tokens are not automatically handled. If tokens expire, the flow will fail silently.
    • Fix: Implement a token refresh mechanism or use Laravel’s cache to store tokens temporarily.
  5. User Data Mutability

    • Google’s user data (e.g., email_verified) may change over time. Cache this data if relying on it for critical logic.
    • Tip: Store a last_sync timestamp in your users table and periodically refresh data.

Debugging Tips

  1. Enable Logging Add this to config/logging.php to debug OAuth issues:

    'channels' => [
        'google_oauth' => [
            'driver' => 'single',
            'path' => storage_path('logs/google_oauth.log'),
            'level' => 'debug',
        ],
    ],
    

    Then inject the logger into your controller:

    public function __construct(\Psr\Log\LoggerInterface $logger) {
        $this->logger = $logger;
    }
    
  2. Test Locally with Google’s Test Users Use Google’s test accounts to avoid rate limits during development.

  3. Inspect the OAuth Response Dump the raw response from Google to debug:

    $response = $googleOauth2->getGoogleClient()->fetchAccessTokenWithAuthCode($request->query('code'));
    dd($response);
    

Extension Points

  1. Custom User Provider Override the default user mapping by extending the service:

    // app/Providers/GoogleOauth2ServiceProvider.php
    public function register()
    {
        $this->app->bind(\Defineweb\GoogleOauth2Bundle\Contracts\UserProvider::class, function () {
            return new CustomGoogleUserProvider();
        });
    }
    
  2. Add Custom Claims Extend the getUser() method by modifying the service:

    // app/Services/ExtendedGoogleOauth2.php
    class ExtendedGoogleOauth2 extends \Defineweb\GoogleOauth2Bundle\GoogleOauth2
    {
        public function getUser()
        {
            $user = parent::getUser();
            $user['custom_field'] = $this->fetchCustomData();
            return $user;
        }
    }
    
  3. Multi-Tenant Support Use middleware to scope the Google client per tenant:

    // app/Http/Middleware/GoogleOauth2TenantMiddleware.php
    public function handle($request, Closure $next)
    {
        $tenant = Tenant::resolve();
        $googleOauth2 = app(GoogleOauth2::class)->setClientId($tenant->google_client_id);
        $request->merge(['google_oauth2' => $googleOauth2]);
        return $next($request);
    }
    
  4. Offline Access Request offline access to get a refresh token:

    GOOGLE_OAUTH2_SCOPES="https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email offline"
    

    Then fetch the refresh token:

    $tokenResponse = $googleOauth2->getGoogleClient()->fetchAccessTokenWithAuthCode($request->query('code'));
    $refreshToken = $tokenResponse['refresh_token'] ?? null;
    
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.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor