How to Use Google OAuth2 with Laravel Socialite for User Authentication

January 14, 2025 · 5 min read

Integrating Google OAuth2 into your Laravel application is an excellent way to offer users a seamless login experience using their Google accounts. Laravel Socialite simplifies this process by providing a straightforward way to authenticate with various providers, including Google. This guide will walk you through setting up Google OAuth2 in your Laravel app and we also have another guide for Microsoft OAuth2 integration.
Besides the official Laravel Socialite package that supports Google, Facebook, X, LinkedIn, GitHub, GitLab, Bitbucket, and Slack, the community package SocialiteProviders also supports integrations like Apple, Steam, Instagram, Discord, Reddit, Snapchat, Telegram, Threads, TikTok, Yahoo, Dropbox, Twitch, Asana, Trello, Zoom, Spotify and many more.
We will also save the user’s last login method on that specific device, so we can show it to them on their next login attempt. This will help prevent users from registering for multiple accounts with both Google and Microsoft.

Step 1: Create a Google Cloud Project
To use Google OAuth2, you need to have a Google Cloud Project. Here’s how to set it up:
Create a Google Cloud Project
Go to the Google Cloud Console.
Click on the link that says "Create or select a project".
Enter a name for your project and click "Create".

Enable APIs and Services
From the Dashboard, navigate to the "Quick Access" section.
Click on "APIs & Services".

Configure the OAuth Consent Screen
Select "OAuth consent screen" from the left sidebar.
If prompted, choose
Go to new experienceto access the updated interface.

Set Up the Consent Screen
Fill in the following information:
App Name: Enter your application's name, for example "socialite"
Support Email: Provide an email address for user support.
User Type: Choose "External" to allow any Google user to authenticate.
Contact Email: Enter a contact email for Google to reach you.
Complete the setup by clicking "Save and Continue" and agreeing to the terms.

Choose "External" for the audience:

Create OAuth Client Credentials
Go to the "Credentials" tab in the APIs & Services section.
Click on "Create Credentials" and select "OAuth client ID".

If you can’t continue with the next step, wait a few minutes and then try again.
Configure OAuth Client
Choose "Web application" as the application type.
Under "Authorized redirect URIs", add the URLs where Google will send users after they authenticate. For local development, you might use
http://localhost:8000/auth/google/callback. For production, use your app’s URL, likehttps://socialite.com/auth/google/callback.Click "Create" to generate the credentials.

Retrieve Your Client ID and Secret
After creation, you’ll see a dialog with your new client ID and client secret.
Copy these values and add them to your Laravel
.envfile.

Step 2: Install Laravel Socialite Package
To enable OAuth2 authentication with providers like Google in your Laravel application, you’ll need to install the Laravel Socialite package. Follow these steps:
Install Laravel Socialite
Use Composer to install the Socialite package:
composer require laravel/socialite
Update Environment Variables
Add the necessary environment variables for Google to your .env file. You’ll use the client IDs and secrets obtained from the project creation step:
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
GOOGLE_REDIRECT_URI=http://localhost:8000/auth/google/callbackStep 3: Configure Laravel Backend
Update the services file
Add configurations for Google OAuth services at the config/services.php file:
return [
// Rest of the code
'google' => [
'client_id' => env('GOOGLE_CLIENT_ID'),
'client_secret' => env('GOOGLE_CLIENT_SECRET'),
'redirect' => env('GOOGLE_REDIRECT_URI'),
],
];Set Up Routing
Define routes for redirecting to Google and handling the callbacks on the routes/auth.php file:
use App\Http\Controllers\Auth\LoginUserViaSocialiteController;
use Illuminate\Support\Facades\Route;
// Rest of the code
Route::get('auth/{provider}/redirect', [LoginUserViaSocialiteController::class, 'create'])->where('provider', 'google|microsoft');
Route::get('auth/{provider}/callback', [LoginUserViaSocialiteController::class, 'store'])->where('provider', 'google|microsoft');Create the Controller
Implement the LoginUserViaSocialiteController controller methods to handle OAuth redirection and callback:
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Laravel\Socialite\Facades\Socialite;
class LoginUserViaSocialiteController extends Controller
{
public function create($provider)
{
// Redirect the user to the Google/Microsoft login page
return Socialite::driver($provider)->redirect();
}
public function store($provider)
{
// Get the user from the Google/Microsoft callback
$socialiteUser = Socialite::driver($provider)->user();
// Check if the user exists
$user = User::where('email', $socialiteUser->getEmail())->first();
// If the user does not exist, do not log them in and redirect them to the login page
if (!$user) {
return redirect()->route('login');
}
// Update the user's socialite_id and socialite_token
$user->update([
'socialite_id' => $socialiteUser->getId(),
'socialite_token' => $socialiteUser->token,
]);
// Log the user in
Auth::login($user);
// Redirect the user to the dashboard
return redirect(route('dashboard'));
}
}Step 4: Add Authentication Buttons in the Frontend
Create Login View
In your login view, add buttons for Google login. Also, include logic to display the tooltip indicating the last used login method.
import Checkbox from '@/components/checkbox'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import InputError from '@/components/ui/input-error'
import InputLabel from '@/components/ui/input-label'
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from '@/components/ui/tooltip'
import GuestLayout from '@/layouts/guest-layout'
import { Head, Link, useForm } from '@inertiajs/react'
import { FormEventHandler } from 'react'
import { useLocalStorage } from '@/hooks/useLocalStorage'
import SVG from 'react-inlinesvg'
export default function Login({
status,
canResetPassword,
}: {
status?: string
canResetPassword: boolean
}) {
const { data, setData, post, processing, errors, reset } = useForm({
email: '',
password: '',
remember: false,
})
const { setItem, getItem } = useLocalStorage('lastLoginMethod')
const submit: FormEventHandler = (e) => {
e.preventDefault()
post(route('login'), {
onFinish: () => {
reset('password')
setItem('Email')
},
})
}
const handleSocialLogin = (
e: React.MouseEvent<HTMLSpanElement>,
method: string,
url: string
) => {
e.preventDefault()
setItem(method)
window.location.href = url
}
return (
<GuestLayout>
<Head title="Log in" />
{status && (
<div className="mb-4 text-center font-medium text-green-600 text-sm">
{status}
</div>
)}
<div className="mx-auto flex w-full flex-col justify-center space-y-6 sm:w-[350px]">
<div className="flex flex-col space-y-2 text-center">
<h1 className="font-semibold text-2xl tracking-tight">
Log in to your account
</h1>
<p className="text-muted-foreground text-sm">
Enter your email below to create your account
</p>
</div>
<div className="grid gap-6">
<form onSubmit={submit}>
<div className="grid gap-2">
<InputLabel htmlFor="email" value="Email" className="sr-only" />
<Input
id="email"
type="email"
name="email"
value={data.email}
placeholder="name@example.com"
className="mt-1 block w-full"
autoCapitalize="none"
autoComplete="email"
autoCorrect="off"
onChange={(e) => setData('email', e.target.value)}
/>
<InputError message={errors.email} className="mt-2" />
</div>
<div className="mt-4">
<InputLabel
htmlFor="password"
value="Password"
className="sr-only"
/>
<Input
id="password"
type="password"
name="password"
value={data.password}
className="mt-1 block w-full"
autoComplete="current-password"
onChange={(e) => setData('password', e.target.value)}
/>
<InputError message={errors.password} className="mt-2" />
</div>
<div className="mt-4 block">
<label
htmlFor="remember"
className="flex items-center justify-between"
>
<div>
<Checkbox
name="remember"
checked={data.remember}
onChange={(e) => setData('remember', e.target.checked)}
/>
<span className="ms-2 text-gray-600 text-sm">
Remember me
</span>
</div>
{canResetPassword && (
<Link
href={route('password.request')}
className="rounded-md text-gray-600 text-sm underline hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
>
Forgot your password?
</Link>
)}
</label>
</div>
<LastLoginMethod defaultOpen={getItem() === 'Email'}>
<Button className="mt-4 w-full" disabled={processing}>
Sign In with Email
</Button>
</LastLoginMethod>
</form>
<div className="relative">
<div className="absolute inset-0 flex items-center">
<span className="w-full border-t" />
</div>
<div className="relative flex justify-center text-xs uppercase">
<span className="bg-background px-2 text-muted-foreground">
Or continue with
</span>
</div>
</div>
<div className="flex flex-col space-y-2">
<LastLoginMethod defaultOpen={getItem() === 'Google'}>
<Button
asChild
type="button"
variant="outline"
className="w-full"
onClick={(e) =>
handleSocialLogin(e, 'Google', '/auth/google/redirect')
}
>
<span className="hover:cursor-pointer">
<SVG src="/svg/google.svg" className="mr-2 size-5" />
Login with Google
</span>
</Button>
</LastLoginMethod>
<LastLoginMethod defaultOpen={getItem() === 'Microsoft'}>
<Button
asChild
type="button"
variant="outline"
className="w-full"
onClick={(e) =>
handleSocialLogin(e, 'Microsoft', '/auth/microsoft/redirect')
}
>
<span className="hover:cursor-pointer">
<SVG src="/svg/microsoft.svg" className="mr-2 size-5" />
Login with Microsoft
</span>
</Button>
</LastLoginMethod>
{getItem() !== undefined ? (
<p className="my-4 text-center font-medium text-gray-600 text-sm">
Your last login method was with: {getItem()}
</p>
) : null}
</div>
</div>
</div>
</GuestLayout>
)
}Store and Retrieve User’s Last Login Method:
When a user logs in via any method, store their choice (Google, Microsoft, or email) in the session or user profile.
Display this information as a tooltip or message in the login view.
This component uses a tooltip to provide feedback on the last used login method.
const LastLoginMethod = ({
children,
defaultOpen,
}: {
children: React.ReactElement
defaultOpen: boolean
}) => {
return (
<TooltipProvider>
<Tooltip defaultOpen={defaultOpen}>
<TooltipTrigger asChild>{children}</TooltipTrigger>
<TooltipContent side="right">
<p>Last used</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
)
}Note: Use localhost instead of .test
As for the development mode, don’t use a `.test` URL for this project. We’ve configured the Google project to work with http://localhost:8000/. You’ll need to serve your app through `php artisan serve` and access it with `localhost`. If you want to skip the frontend code and only test the backend, simply visit the route http://localhost:8000/auth/google/redirect and it should redirect you to the Google authentication page.
Conclusion
You can now integrate Google OAuth2 into your Laravel application using the official Laravel Socialite package. This allows users to sign in with their Google accounts, making the login process more seamless and enhancing the security of your application.
Bring Your Ideas to Life 🚀
If you need help with a Laravel project let’s get in touch.
Lucky Media is proud to be recognized as a leading Laravel Development Agency
Technologies

Stay up-to-date
Be updated with all news, products and tips we share!
On this page
- Step 1: Create a Google Cloud Project
- Create a Google Cloud Project
- Enable APIs and Services
- Configure the OAuth Consent Screen
- Set Up the Consent Screen
- Create OAuth Client Credentials
- Configure OAuth Client
- Retrieve Your Client ID and Secret
- Step 2: Install Laravel Socialite Package
- Step 3: Configure Laravel Backend
- Step 4: Add Authentication Buttons in the Frontend
- Note: Use localhost instead of .test
- Conclusion
- Bring Your Ideas to Life 🚀

