Laravel Tutorials

Connecting Laravel Socialite with Google Client PHP Library

Published
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).

Sponsored

laravelcloud logo
Laravel Cloud

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

Visit Laravel Cloud

The latest

View all →
CPX: The Composer Package Executor for PHP image

CPX: The Composer Package Executor for PHP

Read article
Laravel AI SDK Adds Human-in-the-Loop Tool Approval image

Laravel AI SDK Adds Human-in-the-Loop Tool Approval

Read article
Pest 5 Released With Test Impact Analysis, Agent Verification, and Evals image

Pest 5 Released With Test Impact Analysis, Agent Verification, and Evals

Read article
Queue-SQL: Run Mass Deletes and Updates Across Parallel Queue Jobs image

Queue-SQL: Run Mass Deletes and Updates Across Parallel Queue Jobs

Read article
Blade Formatting in Laravel Pint image

Blade Formatting in Laravel Pint

Read article
Inertia DevTools Is Now on the Chrome Web Store image

Inertia DevTools Is Now on the Chrome Web Store

Read article