In this tutorial, we will show you how to add the Sign in with Google button to your Filament panel.
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.
If you want more Filament examples, you can find more real-life projects on our FilamentExamples.com.
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:
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)
Filament has the Login page built with Livewire so sending
->withErrors()
does not work automatically. There is a few things you can do:While both options are not ideal - I'm not sure if there is a better one at this point
thanks a lot for your hints... i'll have a look to the first one :) have a nice day! j:o)