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.
Install the package:
composer require league/oauth2-google
Register Google OAuth credentials:
http://your-app.test/google/callback).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
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');
}
}
Add routes:
Route::get('/auth/google', [GoogleAuthController::class, 'redirectToGoogle']);
Route::get('/auth/google/callback', [GoogleAuthController::class, 'handleGoogleCallback']);
// 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();
// 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]);
profile, email, openid) during authorization.$authUrl = $provider->getAuthorizationUrl([
'scope' => ['https://www.googleapis.com/auth/userinfo.profile',
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/calendar']
]);
hostedDomain.$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
]);
$provider = new Google([
'clientId' => env('GOOGLE_CLIENT_ID'),
'clientSecret' => env('GOOGLE_CLIENT_SECRET'),
'redirectUri' => env('GOOGLE_REDIRECT_URI'),
'accessType' => 'offline',
]);
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'),
]);
});
}
}
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);
}
}
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(),
]
);
}
}
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]);
});
State Parameter Mismatch:
state parameter in the callback to prevent CSRF attacks.// Before redirect
session(['oauth2state' => $provider->getState()]);
// On callback
if (empty($_GET['state']) || ($_GET['state'] !== session('oauth2state'))) {
throw new \Exception('Invalid state parameter');
}
Redirect URI Mismatch:
redirectUri in your code matches exactly (including http vs https) the URI registered in Google Cloud Console.Refresh Token Limitations:
prompt=consent and access_type=offline.Scopes and Permissions:
['https://www.googleapis.com/auth/userinfo
How can I help you explore Laravel packages today?