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

Oauth2 Google Laravel Package

league/oauth2-google

Google OAuth 2.0 provider for thephpleague/oauth2-client. Implements OpenID Connect sign-in with Google, supports Authorization Code flow, and helps fetch user details and tokens using your Google client ID/secret. Compatible with PHP 8.x.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup in Laravel

  1. Install the package:

    composer require league/oauth2-google
    
  2. Register Google OAuth credentials:

    • Create a project in Google Cloud Console.
    • Navigate to APIs & Services > Credentials and create an OAuth Client ID.
    • Add authorized redirect URIs (e.g., http://your-app.test/google/callback).
  3. Store credentials in .env:

    GOOGLE_CLIENT_ID=your-client-id
    GOOGLE_CLIENT_SECRET=your-client-secret
    GOOGLE_REDIRECT_URI=http://your-app.test/google/callback
    
  4. First use case: Authenticate a user Create a controller to handle the OAuth flow:

    use League\OAuth2\Client\Provider\Google;
    use League\OAuth2\Client\Token\AccessToken;
    
    class GoogleAuthController extends Controller
    {
        public function redirectToGoogle()
        {
            $provider = new Google([
                'clientId'     => env('GOOGLE_CLIENT_ID'),
                'clientSecret' => env('GOOGLE_CLIENT_SECRET'),
                'redirectUri'  => env('GOOGLE_REDIRECT_URI'),
            ]);
    
            $authUrl = $provider->getAuthorizationUrl();
            return redirect()->to($authUrl);
        }
    
        public function handleGoogleCallback(Request $request)
        {
            $provider = new Google([
                'clientId'     => env('GOOGLE_CLIENT_ID'),
                'clientSecret' => env('GOOGLE_CLIENT_SECRET'),
                'redirectUri'  => env('GOOGLE_REDIRECT_URI'),
            ]);
    
            $code = $request->query('code');
            $token = $provider->getAccessToken('authorization_code', ['code' => $code]);
            $user = $provider->getResourceOwner($token);
    
            // Store user data in session or database
            auth()->loginUsingId($user->getId(), true);
    
            return redirect()->route('dashboard');
        }
    }
    
  5. Add routes:

    Route::get('/auth/google', [GoogleAuthController::class, 'redirectToGoogle']);
    Route::get('/auth/google/callback', [GoogleAuthController::class, 'handleGoogleCallback']);
    

Implementation Patterns

Workflows

1. Standard OAuth Flow

  • Redirect to Google: Generate an authorization URL and redirect the user.
  • Handle Callback: Exchange the authorization code for an access token.
  • Fetch User Data: Retrieve user details using the access token.
  • Store Session: Save user data (e.g., email, name) in Laravel's session or database.
// Redirect to Google
$provider = new Google([...]);
$authUrl = $provider->getAuthorizationUrl(['scope' => ['profile', 'email']]);
return redirect()->to($authUrl);

// Handle callback
$token = $provider->getAccessToken('authorization_code', ['code' => $request->code]);
$user = $provider->getResourceOwner($token);

// Use user data
$email = $user->getEmail();
$name = $user->getFirstName() . ' ' . $user->getLastName();

2. Refreshing Tokens

  • Store the refresh token securely (e.g., in the database).
  • Use the refresh token to get a new access token when it expires.
// Store refresh token
$refreshToken = $token->getRefreshToken();
User::createOrUpdateFromGoogle($refreshToken, $userData);

// Refresh token later
$grant = new \League\OAuth2\Client\Grant\RefreshToken();
$newToken = $provider->getAccessToken($grant, ['refresh_token' => $refreshToken]);

3. Scopes and Permissions

  • Request additional scopes (e.g., profile, email, openid) during authorization.
  • Use scopes to access specific Google APIs (e.g., Google Drive, Calendar).
$authUrl = $provider->getAuthorizationUrl([
    'scope' => ['https://www.googleapis.com/auth/userinfo.profile',
                'https://www.googleapis.com/auth/userinfo.email',
                'https://www.googleapis.com/auth/calendar']
]);

4. G Suite/Google Workspace Integration

  • Restrict access to users within a specific domain using hostedDomain.
  • Useful for enterprise applications.
$provider = new Google([
    'clientId'     => env('GOOGLE_CLIENT_ID'),
    'clientSecret' => env('GOOGLE_CLIENT_SECRET'),
    'redirectUri'  => env('GOOGLE_REDIRECT_URI'),
    'hostedDomain' => 'yourcompany.com', // Only allow users from this domain
]);

5. Offline Access

  • Request offline access to obtain a refresh token for long-lived sessions.
  • Useful for background jobs or server-to-server interactions.
$provider = new Google([
    'clientId'     => env('GOOGLE_CLIENT_ID'),
    'clientSecret' => env('GOOGLE_CLIENT_SECRET'),
    'redirectUri'  => env('GOOGLE_REDIRECT_URI'),
    'accessType'   => 'offline',
]);

Integration Tips

Laravel Service Provider

Create a service provider to encapsulate Google OAuth logic:

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use League\OAuth2\Client\Provider\Google;

class GoogleAuthServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->singleton(Google::class, function ($app) {
            return new Google([
                'clientId'     => env('GOOGLE_CLIENT_ID'),
                'clientSecret' => env('GOOGLE_CLIENT_SECRET'),
                'redirectUri'  => env('GOOGLE_REDIRECT_URI'),
            ]);
        });
    }
}

Middleware for Authenticated Users

Create middleware to verify Google authentication:

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class AuthenticateWithGoogle
{
    public function handle(Request $request, Closure $next)
    {
        if (!$request->user() || !$request->user()->google_id) {
            return redirect()->route('login');
        }
        return $next($request);
    }
}

User Model Integration

Extend Laravel's User model to handle Google data:

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use League\OAuth2\Client\Provider\ResourceOwnerInterface;

class User extends Authenticatable
{
    public static function createFromGoogle(ResourceOwnerInterface $googleUser)
    {
        return static::updateOrCreate(
            ['email' => $googleUser->getEmail()],
            [
                'name' => $googleUser->getFirstName() . ' ' . $googleUser->getLastName(),
                'google_id' => $googleUser->getId(),
                'avatar' => $googleUser->getAvatar(),
            ]
        );
    }
}

Caching Tokens

Use Laravel's cache to store access tokens temporarily:

$token = cache()->remember('google_token_' . $user->id, now()->addHours(1), function () use ($provider, $refreshToken) {
    $grant = new \League\OAuth2\Client\Grant\RefreshToken();
    return $provider->getAccessToken($grant, ['refresh_token' => $refreshToken]);
});

Gotchas and Tips

Pitfalls

  1. State Parameter Mismatch:

    • Always validate the state parameter in the callback to prevent CSRF attacks.
    • Store the state in the session before redirecting to Google and compare it on callback.
    // Before redirect
    session(['oauth2state' => $provider->getState()]);
    
    // On callback
    if (empty($_GET['state']) || ($_GET['state'] !== session('oauth2state'))) {
        throw new \Exception('Invalid state parameter');
    }
    
  2. Redirect URI Mismatch:

    • Ensure the redirectUri in your code matches exactly (including http vs https) the URI registered in Google Cloud Console.
    • Google will reject the request if they don’t match.
  3. Refresh Token Limitations:

    • Refresh tokens are only returned once (on the first authorization code exchange).
    • Subsequent refreshes will return a new access token but not a new refresh token.
    • To get a new refresh token, force the user to re-consent using prompt=consent and access_type=offline.
  4. Scopes and Permissions:

    • Google may reject requests with unsupported or invalid scopes.
    • Always check the Google Scopes documentation for valid scopes.
    • Example of valid scopes:
      ['https://www.googleapis.com/auth/userinfo
      
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