Filament: Login with Google using Laravel Socialite

In this tutorial, we will show you how to add the Sign in with Google button to your Filament panel.

Filament Socialite

First, we must Install the Laravel Socialite package.

composer require laravel/socialite

Then, define your configuration values for Google.

config/services.php

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

Specify your API Credentials in the environment file.

.env

GOOGLE_CLIENT_ID=******
GOOGLE_CLIENT_SECRET=******

Google Sign-In blocks any insecure login requests. OAuth requests always require that your application support HTTPS schema. Please make sure that your app has an SSL certificate.

You can force that your generated URLs always use HTTP schema by updating AppServiceProvider.

app/Providers/AppServiceProvider.php

use Illuminate\Support\Facades\URL;
 
public function boot(): void
{
URL::forceScheme('https');
}

Add the google_id field into your users table.

php artisan make:migration add_google_id_column_to_users_table

Update the up() method of migration.

database/migrations/XXXXXX_add_google_id_column_to_users_table.php

Schema::table('users', function (Blueprint $table) {
$table->string('google_id')->nullable();
});

Append the $fillable array of your User Model.

app/Models/User.php

protected $fillable = [
// ...
'google_id',
// ...

Create a new controller for Socialite login.

app/Http/Controllers/SocialiteController.php

namespace App\Http\Controllers;
 
use App\Models\User;
use Laravel\Socialite\Facades\Socialite;
 
class SocialiteController extends Controller
{
public function redirect(string $provider)
{
$this->validateProvider($provider);
 
return Socialite::driver($provider)->redirect();
}
 
public function callback(string $provider)
{
$this->validateProvider($provider);
 
$response = Socialite::driver($provider)->user();
 
$user = User::firstWhere(['email' => $response->getEmail()]);
 
if ($user) {
$user->update([$provider . '_id' => $response->getId()]);
} else {
$user = User::create([
$provider . '_id' => $response->getId(),
'name' => $response->getName(),
'email' => $response->getEmail(),
'password' => '',
]);
}
 
auth()->login($user);
 
return redirect()->intended(route('filament.admin.pages.dashboard'));
}
 
protected function validateProvider(string $provider): array
{
return $this->getValidationFactory()->make(
['provider' => $provider],
['provider' => 'in:google']
)->validate();
}
}

And define routes for the SocialiteController in the web.php file.

routes/web.php

use App\Http\Controllers\SocialiteController;
 
Route::get('/auth/{provider}/redirect', [SocialiteController::class, 'redirect'])
->name('socialite.redirect');
Route::get('/auth/{provider}/callback', [SocialiteController::class, 'callback'])
->name('socialite.callback');

Now, we can create a new Blade View.

resources/views/auth/socialite/google.blade.php

<x-filament::button
:href="route('socialite.redirect', 'google')"
tag="a"
color="info"
>
Sign in with Google
</x-filament::button>

And inject it with the panels::auth.login.form.after hook in the AdminPanelProvider file.

app/Providers/Filament/AdminPanelProvider.php

public function panel(Panel $panel): Panel
{
return $panel
// ...
->renderHook(
'panels::auth.login.form.after',
fn () => view('auth.socialite.google')
);
}

You should be able to see the result when you visit the /admin/login page.

Filament Socialite


If you want more Filament examples, you can find more real-life projects on our FilamentExamples.com.

avatar

Hi, My application requires that the user exists beforehand, i've then modified the callback method of the SocialiteController in order to redirect to filament login when user does not exist:

    $user = User::firstWhere(['email' => $response->getEmail()]);
    if (!$user) {
            return redirect()->route('filament.admin.auth.login')->withErrors([
                'email' => 'Unknown user.',
            ]);
    }

But I cannot display the error on the Filament login page, the $errors bag seems to be empty. Any hint how to display this error on the Filament login page? Thanks... J:o)

avatar

Filament has the Login page built with Livewire so sending ->withErrors() does not work automatically. There is a few things you can do:

  1. Build a custom page that is not the "Login" page and show that to users that are not in the system
  2. Re-build the Filament Login page manually and add the missing information (for example, you can use a URL parameter to trigger the validation message).

While both options are not ideal - I'm not sure if there is a better one at this point

avatar

thanks a lot for your hints... i'll have a look to the first one :) have a nice day! j:o)

avatar

How can I remove default username/password login method?

avatar

When doing a custom page, you can just remove the form from the template. That should do it!

avatar

Thank you. I have created resources/views/vendor/filament-panels/pages/auth/login.blade.php and customized it as I need.

avatar
class Login extends \Filament\Pages\Auth\Login
{
    public function form(Form $form): Form
    {
        return $form
            ->schema([
                //                $this->getEmailFormComponent(),
                //                $this->getPasswordFormComponent(),
                //                $this->getRememberFormComponent(),
            ]);
    }

    protected function getFormActions(): array
    {
        return [
            Action::make('google_login')->view('auth.socialite.google'),
        ];
    }

    public function getHeading(): string|Htmlable
    {
        //Default is 'Sign in'
        return '';
    }
}

I think this is the way.

Like our articles?

Become a Premium Member for $129/year or $29/month
What else you will get:
  • 59 courses (1057 lessons, total 42 h 44 min)
  • 79 long-form tutorials (one new every week)
  • access to project repositories
  • access to private Discord

Recent Premium Tutorials