
How to Implement Google Socialite in Laravel
Introduction
Social authentication has become an essential feature in modern web applications. In this article, we’ll explore how to implement Google authentication in Laravel using Laravel Socialite, with a focus on creating a flexible and secure implementation that works across different environments.
Steps for logging in with a Gmail Account in Laravel
-
Step 1: Installing Laravel
-
Step 2: Install Laravel Breeze
-
Step 3: Install Laravel Socialite
-
Step 4: Create a Google App
-
Step 5: Add the
google_id
column -
Step 6: Create Routes
-
Step 7: Create Controller
-
Step 8: Update Blade File
-
Run Laravel App
Step 1: Installing Laravel
This step is not required; however, if you have not created the Laravel app, then you may go ahead and execute the following command:
laravel new social-auth-tutorial
Step 2: Installing Laravel Breeze
Now, in this step, we need to use the Composer command to install Laravel Breeze, so let's run the following command and install the Breeze package:
composer require laravel/breeze
Once the package is installed, we also need to run the breeze:install
command to properly install Laravel Breeze into our project:
php artisan breeze:install
Step 3: Install Socialite
composer require laravel/socialite
Step 4: Create a Google App
Go to https://console.cloud.google.com/projectcreate and create a new project.
Once the project is created, click on the Get Started button of the Clients tab, since we need to create a new OAuth Client
You now need to provide the app details like the App name and support email, as shown in the image below:
On the audience tab, select External and click next:
You also need to provide the email contact so that Google can notify you about any changes that might happen to your app.
Once you complete this flow, you will be redirected to the OAuth Overview page. Click on the Create OAuth Client
Button
On this page, set the application type as Web and provide the name of your app, also Add "Authorized redirect URI", and click on "CREATE" as shown in the following image:
Once that is created, you will now be able to copy the client_id and the client_secret, which we will paste into our .env, and to copy both of these credentials, we need to click on the edit button of the Clients Overview page:
On the right side of this page, you can see the client ID and the Client secret, copy and save these since we’ll be needing them later.
Now we have to set the Client ID
, Client Secret
, and the callback URL
in the services.php config file, so open config/services.php and set the ID, secret and callback URL this way:
return [
....
'google' => [
'client_id' => env('GOOGLE_CLIENT_ID'),
'client_secret' => env('GOOGLE_CLIENT_SECRET'),
'redirect' => env('GOOGLE_REDIRECT'),
],
]
Then you need to add Google client ID and client secret in the .env file, along with the GOOGLE_REDIRECT key:
GOOGLE_CLIENT_ID=XXXXXsvqcn3d.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=XXXXXT6tR1rWpR-Jxy3jkdzs
GOOGLE_REDIRECT=http://127.0.0.1:8000/auth/callback/google
Step 5: Add the google_id
column
In this step, first, we have to create a migration to add the google_id
In our users’ table. So let's run the below command:
php artisan make:migration add_google_id_column
We’ll also set the password as a nullable column, since we won’t be defining a password when a user signs up with Google.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up(): void
{
Schema::table('users', function ($table) {
$table->string('password')->nullable()->change();
$table->string('google_id')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down(): void
{
$table->string('password');
$table->dropColumn('google_id');
}
};
Let’s now update the User Model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name',
'email',
'password',
'google_id'
];
/**
* The attributes that should be hidden for serialization.
*
* @var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* Get the attributes that should be cast.
*
* @return array
*/
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
}
Step 6: Create Routes
After adding the google_id
column, we have to add new routes for Google login. So let's add the below route in the routes.php
file.
routes/web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\GoogleController;
Route::get('/', function () {
return view('welcome');
});
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
Route::controller(GoogleController::class)->group(function(){
Route::get('auth/google', 'redirect')->name('auth.google');
Route::get('auth/google/callback', 'handleCallback');
});
Step 7: Defining the Controller
After adding the routes, we need to define the necessary methods in our controller for handling the Google authentication flow.
app/Http/Controllers/GoogleController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Laravel\Socialite\Facades\Socialite;
use Exception;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
class GoogleController extends Controller
{
/**
* Create a new controller instance.
*
* @return void
*/
public function redirectToGoogle()
{
return Socialite::driver('google')->redirect();
}
/**
* Create a new controller instance.
*
* @return void
*/
public function handleGoogleCallback()
{
try {
$user = Socialite::driver('google')->user();
$userFromDb = User::where('google_id', $user->id)->first();
if($userFromDb){
Auth::login($userFromDb);
return redirect()->intended('home');
}else{
$newUser = User::updateOrCreate(['email' => $user->email],[
'name' => $user->name,
'google_id'=> $user->id,
]);
Auth::login($newUser);
return redirect()->intended('home');
}
} catch (Exception $e) {
// implement proper error handling here
}
}
}
Step 8: Updating the Frontend Files
The last step remaining in this flow is to update the login/registration file to include a link to the Google OAuth flow, so that the user can click on it, to either log in or register with their Google account.
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Login') }}</div>
<div class="card-body">
<form method="POST" action="{{ route('login') }}">
@csrf
<div class="row mb-3">
<label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Email Address') }}</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
@error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<label for="password" class="col-md-4 col-form-label text-md-end">{{ __('Password') }}</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">
@error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="row mb-3">
<div class="col-md-6 offset-md-4">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>
<label class="form-check-label" for="remember">
{{ __('Remember Me') }}
</label>
</div>
</div>
</div>
<div class="row mb-0">
<div class="col-md-8 offset-md-4">
<button type="submit" class="btn btn-primary">
{{ __('Login') }}
</button>
@if (Route::has('password.request'))
<a class="btn btn-link" href="{{ route('password.request') }}">
{{ __('Forgot Your Password?') }}
</a>
@endif
</div>
</div>
<div class="row mb-0">
<div class="col-md-8 offset-md-4">
<br/>
<a href="{{ route('auth.google') }}">
<img src="https://developers.google.com/identity/images/btn_google_signin_dark_normal_web.png">
</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
Running the Laravel App:
All the required steps have been done, now you have to type the command below and hit enter to run the Laravel app:
php artisan serve
Now, go to your web browser, type the given URL, and view the app output:
http://localhost:8000/login
Conclusion
And that’s it, we have now implemented a Google sign-in feature in our Laravel App. I hope this was helpful.