Connecting Laravel Socialite with Google Client PHP Library

Published on by

Connecting Laravel Socialite with Google Client PHP Library image

OAuth authentication has become a standard for web applications, allowing users to log in using their existing accounts from services like Google. Laravel Socialite makes this process straightforward, but what if you want to go beyond simple authentication and access Google's APIs like Calendar? This article will guide you through setting up Laravel Socialite with Google OAuth and connecting it to the Google Client PHP Library.

Setting Up Laravel Socialite

First, create a new Laravel project and install Socialite:

composer create-project laravel/laravel google
composer require laravel/socialite

Add Google OAuth credentials to your config/services.php file:

'google' => [
'client_id' => env('GOOGLE_CLIENT_ID'),
'client_secret' => env('GOOGLE_CLIENT_SECRET'),
'redirect' => 'http://localhost:8000/auth/callback',
],

Creating Google OAuth Credentials

Because it has a lot of steps, this part is always a bit tricky.

  1. Go to the Google Cloud Console
  2. Navigate to "APIs & Services > Credentials"
  3. Set up your OAuth consent screen if you haven't already
  4. Click "Create Credentials" and select "OAuth client ID"
  5. Choose "Web Application" as your application type and give it a name
  6. Add an authorized redirect URI (e.g., http://localhost:8000/auth/callback or http://yoursite.test/auth/callback if using Laravel Herd)
  7. After creation, you'll receive your Client ID and Client Secret. You'll add these to your .env file as GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET. You'll also need the credentials file downloaded as JSON. Click "Download JSON" to get this file.
  8. Rename this new JSON file as oauth-credentials.json and place it at storage/app/private/google/oauth-credentials.json

Basic Socialite Implementation

Set up routes in your routes/web.php file for OAuth redirection and callback. I've made changes to the typical setup to store tokens as files and included a route we'll use to handle refresh tokens:

Route::get('/auth/redirect', function ()
{
return Socialite::driver('google')
->scopes(['https://www.googleapis.com/auth/calendar'])
->with([
'prompt' => 'consent',
])
->redirect();
});
 
Route::get('/auth/refresh', function ()
{
$refreshToken = Storage::disk('local')->get('google/oauth-refresh-token.json');
 
$newTokens = Socialite::driver('google')->refreshToken($refreshToken);
 
if($newTokens->token)
{
Storage::disk('local')->put('google/oauth-token.json', $newTokens->token);
}
 
if($newTokens->refreshToken)
{
Storage::disk('local')->put('google/oauth-refresh-token.json', $newTokens->refreshToken);
}
 
return redirect('/gmail');
});
 
Route::get('/auth/callback', function ()
{
$googleUser = Socialite::driver('google')->user();
 
Storage::disk('local')->put('google/oauth-token.json', $googleUser->token);
if($googleUser->refreshToken)
{
Storage::disk('local')->put('google/oauth-refresh-token.json', $googleUser->refreshToken);
}
 
$expiresIn = $googleUser->expiresIn;
 
Auth::login($user);
return redirect('/dashboard');
});

Authorization

Visit http://localhost:8000/auth/redirect to login. You should now see a Google sign-in screen.

Expanding OAuth Scope for Google Calendar Access

Let's say you want to expand the usefulness of this OAuth token exchange. It has been great for getting users logged into your web application, but now you want to have users see events from their Google Calendar. We can change the scope of our OAuth access so fetching Google Calendar events will work. To do this, we'll need a different library.

To access Google Calendar data, we need to enable the Google Calendar API.

  1. Enable the Google Calendar API in Google Cloud Console:

    • Go to "APIs & Services > Library"
    • Search for and enable the Google Calendar API
  2. Modify your redirect route to include the Calendar scope:

Route::get('/auth/redirect', function () {
return Socialite::driver('google')
->scopes(['https://www.googleapis.com/auth/calendar'])
->redirect();
});

Note: You can see a list of different scopes to Google products at https://developers.google.com/identity/protocols/oauth2/scopes

When you visit /auth/redirect, you'll now be prompted to grant access to your Google Calendar.

Note: If you encounter a 403 error, add yourself as a test user under "Google Auth Platform > Audience > Test Users" in the Google Cloud Console.

Connecting to the Google Client PHP Library

But now what? How do you get that calendar data? Simply having the OAuth token isn't enough to access Google Calendar data. For this, we need another library.

I'm going to use the Google APIs Client Library for PHP.

composer require google/apiclient

Create a new route to access the Google Calendar API. Obviously a route might not be the best place for this, but it'll work.

 
use Google\Client;
 
Route::get('/calendar', function ()
{
$client = new Client();
 
// Pluck the same tokens used for Socialite
$oathCredentialsPath = Storage::disk('local')->path('google/oauth-credentials.json');
$refreshToken = Storage::disk('local')->get('google/oauth-refresh-token.json');
$oathToken = Storage::disk('local')->get('google/oauth-token.json');
 
$client->setAuthConfig($oathCredentialsPath);
$client->setAccessToken($oathToken);
$client->addScope(\Google\Service\Calendar::CALENDAR_READONLY);
$service = new \Google_Service_Calendar($client);
 
$calendar_id = 'youremail@gmail.com';
$opt_params = array(
'maxResults' => 10,
'orderBy' => 'startTime',
'singleEvents' => true,
'timeMin' => date('c'),
);
$results = $service->events->listEvents($calendar_id, $opt_params);
dd($results);
 
});

Now, using the tokens you already had from Socialite, you should see Google Calendar events back from the API.

Obtaining and Managing Refresh Tokens

For long-term API access, you'll need a refresh token. Eventually your access token will expire. We created a /auth/refresh route for refreshing a token, but visiting that URL might not work for you the first time. If you don't have a storage/app/private/google/oauth-refresh-token.json file, it will fail. Your first OAauth request likely didn't return a refresh token.

Force Google to provide one by adding the consent prompt to your /auth/redirect route:

Route::get('/auth/redirect', function () {
return Socialite::driver('google')
->scopes(['https://www.googleapis.com/auth/calendar'])
->with([
'prompt' => 'consent',
])
->redirect();
});

An Alternate Way to Handle Token Expiration and Refreshing

You don't have to redirect a user to /auth/refresh for a refresh token, if you don't want. Here's an example of how to handle token refreshing when connecting to Google's APIs in an exception.

The key to making this work is the refreshToken() method from Socialite.

try {
 
// Your attempt to connect to Google API
 
} catch (\Exception $e) {
 
// Refresh Google auth token
$oldRefreshToken = Storage::disk('local')->get('google/oauth-refresh-token.json');
$newTokens = Socialite::driver('google')->refreshToken($oldRefreshToken);
 
if ($newTokens->token) {
Storage::disk('local')->put('google/oauth-token.json', $newTokens->token);
}
 
if ($newTokens->refreshToken) {
Storage::disk('local')->put('google/oauth-refresh-token.json', $newTokens->refreshToken);
}
 
// Try to connect again after refreshing the token
}

Conclusion

By combining Laravel Socialite with the Google Client PHP Library, you can create powerful applications that not only authenticate users but also interact with Google services like Calendar. This approach gives you the flexibility to expand your application's capabilities while maintaining a smooth authentication flow for your users. And it might be a little more efficient for you.

Remember to always handle tokens securely and implement proper error handling for API requests to ensure a secure and robust user experience.

Zac Vineyard photo

I'm a Boise area web developer who's passionate about design, code, and the tools of my craft. Day-to-day I work with PHP, JavaScript, and CSS. I'm currently the director of enrollment marketing technology at Miami University (OH).

Cube

Laravel Newsletter

Join 40k+ other developers and never miss out on new tips, tutorials, and more.

image
Laravel Cloud

Easily create and manage your servers and deploy your Laravel applications in seconds.

Visit Laravel Cloud
Acquaint Softtech logo

Acquaint Softtech

Acquaint Softtech offers AI-ready Laravel developers who onboard in 48 hours at $3000/Month with no lengthy sales process and a 100 percent money-back guarantee.

Acquaint Softtech
Tinkerwell logo

Tinkerwell

The must-have code runner for Laravel developers. Tinker with AI, autocompletion and instant feedback on local and production environments.

Tinkerwell
Laravel Cloud logo

Laravel Cloud

Easily create and manage your servers and deploy your Laravel applications in seconds.

Laravel Cloud
PhpStorm logo

PhpStorm

The go-to PHP IDE with extensive out-of-the-box support for Laravel and its ecosystem.

PhpStorm
Kirschbaum logo

Kirschbaum

Providing innovation and stability to ensure your web application succeeds.

Kirschbaum
Lucky Media logo

Lucky Media

Get Lucky Now - the ideal choice for Laravel Development, with over a decade of experience!

Lucky Media
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit: Laravel SaaS Starter Kit

SaaSykit is a Multi-tenant Laravel SaaS Starter Kit that comes with all features required to run a modern SaaS. Payments, Beautiful Checkout, Admin Panel, User dashboard, Auth, Ready Components, Stats, Blog, Docs and more.

SaaSykit: Laravel SaaS Starter Kit
Shift logo

Shift

Running an old Laravel version? Instant, automated Laravel upgrades and code modernization to keep your applications fresh.

Shift
Harpoon: Next generation time tracking and invoicing logo

Harpoon: Next generation time tracking and invoicing

The next generation time-tracking and billing software that helps your agency plan and forecast a profitable future.

Harpoon: Next generation time tracking and invoicing
No Compromises logo

No Compromises

Joel and Aaron, the two seasoned devs from the No Compromises podcast, are now available to hire for your Laravel project. ⬧ Flat rate of $9500/mo. ⬧ No lengthy sales process. ⬧ No contracts. ⬧ 100% money back guarantee.

No Compromises

The latest

View all →
Bulk Job Dispatching with Bus::bulk() in Laravel 13.13 image

Bulk Job Dispatching with Bus::bulk() in Laravel 13.13

Read article
Audit Laravel Apps for Security Issues with Checkpoint image

Audit Laravel Apps for Security Issues with Checkpoint

Read article
In-Memory Eloquent Models with Truffle image

In-Memory Eloquent Models with Truffle

Read article
Detect and Resolve Laravel Schema Drift with MigrAlign image

Detect and Resolve Laravel Schema Drift with MigrAlign

Read article
Laravel Cloud Adds Scale-to-Zero and Spending Limits image

Laravel Cloud Adds Scale-to-Zero and Spending Limits

Read article
Shift + AI = Fully Automated Laravel Upgrades image

Shift + AI = Fully Automated Laravel Upgrades

Read article