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
Curotec

Curotec helps software teams hire the best Laravel developers in Latin America. Click for rates and to learn more about how it works.

Visit Curotec
Curotec logo

Curotec

World class Laravel experts with GenAI dev skills. LATAM-based, embedded engineers that ship fast, communicate clearly, and elevate your product. No bloat, no BS.

Curotec
Bacancy logo

Bacancy

Supercharge your project with a seasoned Laravel developer with 4-6 years of experience for just $2500/month. Get 160 hours of dedicated expertise & a risk-free 15-day trial. Schedule a call now!

Bacancy
Laravel Forge logo

Laravel Forge

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

Laravel Forge
Tinkerwell logo

Tinkerwell

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

Tinkerwell
Cut PHP Code Review Time & Bugs into Half with CodeRabbit logo

Cut PHP Code Review Time & Bugs into Half with CodeRabbit

CodeRabbit is an AI-powered code review tool that specializes in PHP and Laravel, running PHPStan and offering automated PR analysis, security checks, and custom review features while remaining free for open-source projects.

Cut PHP Code Review Time & Bugs into Half with CodeRabbit
Join the Mastering Laravel community logo

Join the Mastering Laravel community

Connect with experienced developers in a friendly, noise-free environment. Get insights, share ideas, and find support for your coding challenges. Join us today and elevate your Laravel skills!

Join the Mastering Laravel community
Kirschbaum logo

Kirschbaum

Providing innovation and stability to ensure your web application succeeds.

Kirschbaum
Shift logo

Shift

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

Shift
Lucky Media logo

Lucky Media

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

Lucky Media
Lunar: Laravel E-Commerce logo

Lunar: Laravel E-Commerce

E-Commerce for Laravel. An open-source package that brings the power of modern headless e-commerce functionality to Laravel.

Lunar: Laravel E-Commerce
LaraJobs logo

LaraJobs

The official Laravel job board

LaraJobs
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
MongoDB logo

MongoDB

Enhance your PHP applications with the powerful integration of MongoDB and Laravel, empowering developers to build applications with ease and efficiency. Support transactional, search, analytics and mobile use cases while using the familiar Eloquent APIs. Discover how MongoDB's flexible, modern database can transform your Laravel applications.

MongoDB

The latest

View all →
Confidently Extract Single Array Items with Laravel's Arr::sole() Method image

Confidently Extract Single Array Items with Laravel's Arr::sole() Method

Read article
Safely Retry API calls in Laravel image

Safely Retry API calls in Laravel

Read article
Laravel's AsHtmlString Cast for Elegant HTML Attribute Management image

Laravel's AsHtmlString Cast for Elegant HTML Attribute Management

Read article
NativePHP for Mobile v1 — Launching May 2 image

NativePHP for Mobile v1 — Launching May 2

Read article
Map Eloquent Attributes into an Object Using the Collection Cast in Laravel 12.10 image

Map Eloquent Attributes into an Object Using the Collection Cast in Laravel 12.10

Read article
Converting Array Values to Enum Instances with Laravel's mapInto Method image

Converting Array Values to Enum Instances with Laravel's mapInto Method

Read article