How to add GitHub login with Filament Socialite

Learn how to integrate GitHub login in Filament using the Filament Socialite plugin. Step-by-step setup with custom user creation and profile sync.

How to add GitHub login to your Filament Panel with Filament Socialite picture

Adding social login to your Filament application can greatly improve the user experience. In this tutorial, we'll walk through how to enable GitHub login using the Filament Socialite plugin, which is based on Laravel Socialite.

We'll also cover how to create users, handle exceptions, and keep empty profile data in sync with GitHub.

1. Install Filament Socialite

Follow the installation instructions in the official documentation.

composer require dutchcodingcompany/filament-socialite

Publish migration and migrate:

php artisan vendor:publish --tag="filament-socialite-migrations"
php artisan migrate

You may also publish the config and views, but it's not required for this example.

2. Register the plugin in your Panel Provider

In your AdminPanelProvider or custom Panel Provider (like MemberPanelProvider here), register the plugin and define your providers. We'll use GitHub in this example:

<?php

namespace App\Providers\Filament;

use App\Enums\RolesEnum;
use App\Exceptions\SocialiteUnableToCreateUserException;
use App\Exceptions\SocialiteUsernameAlreadyExistsException;
use App\Models\User;
use DutchCodingCompany\FilamentSocialite\FilamentSocialitePlugin;
use DutchCodingCompany\FilamentSocialite\Provider;
use Filament\Panel;
use Filament\PanelProvider;
use Illuminate\Support\Facades\DB;
use Laravel\Socialite\Contracts\User as SocialiteUserContract;

class MemberPanelProvider extends PanelProvider
{
    public function panel(Panel $panel): Panel
    {
        return $panel
            // ...
            ->plugin(
                FilamentSocialitePlugin::make()
                    ->slug('member')
                    ->registration()
                    ->providers([
                        Provider::make('github')
                            ->label('Github')
                            ->icon('fab-github')
                            ->color('primary')
                            ->outlined(false)
                            ->stateless(false)
                            ->scopes(['read:user']),
                    ])
                    ->createUserUsing(function (string $provider, SocialiteUserContract $oauthUser, FilamentSocialitePlugin $plugin) {
                        $username = $oauthUser->getNickname() ?? $oauthUser->getName();

                        if (User::where('username', $username)->exists()) { // Check if username already exists
                            throw new SocialiteUsernameAlreadyExistsException;
                        }

                        DB::beginTransaction();

                        try {
                            $user = User::create([
                                'name' => $oauthUser->getName(),
                                'username' => $username,
                                'email' => $oauthUser->getEmail(),
                                'timezone' => config('app.timezone'),
                            ]);

                            $user->assignRole(RolesEnum::MEMBER->value); 
                            $user->markEmailAsVerified(); // To auto validate user email
                            DB::commit();

                            return $user;
                        } catch (\Exception $exception) {
                            DB::rollBack();
                            logger()->error($exception->getMessage());
                            throw new SocialiteUnableToCreateUserException;
                        }
                    })
            );
    }
}

Explanation

  • ->slug('member'): Override the panel slug to be used in the oauth routes. Defaults to the panel ID.
  • ->registration(): Enables registration for social login.
  • ->providers([...]): Active OAUTH providers.
  • ->createUserUsing(...): Handles custom user creation logic. Here, it's a simplified example.

This configuration adds two routes on your panel :

  • /{slug}/oauth/{provider}: Starts the OAuth login process.
  • /{slug}/oauth/callback/{provider}: Handles the callback after the provider login process (redirect URL).

Custom exceptions let you manage error feedback more cleanly. Here we have two exceptions:

// SocialiteUnableToCreateUserException.php
class SocialiteUnableToCreateUserException extends Exception
{
    public function render(Request $request): RedirectResponse
    {
        session()->put('filament-socialite-login-error', 'Unable to create your account.');
        return response()->redirectTo(filament()->getPanel(FilamentPanelEnum::MEMBER->value)->getLoginUrl());
    }
}

// SocialiteUsernameAlreadyExistsException.php
class SocialiteUsernameAlreadyExistsException extends Exception
{
    public function render(Request $request): RedirectResponse
    {
        session()->put('filament-socialite-login-error', 'Unable to create your account. The associated username already exists.');
        return response()->redirectTo(filament()->getPanel(FilamentPanelEnum::MEMBER->value)->getLoginUrl());
    }
}

3. Manage provider configurations

You need to define Github OAUTH settings on your services.php file:

'github' => [
		'client_id' => env('GITHUB_CLIENT_ID'),
		'client_secret' => env('GITHUB_CLIENT_SECRET'),
		'redirect' => env('GITHUB_OAUTH_REDIRECT'),
],

And add the associated environment variables in your .env file.

  • GITHUB_OAUTH_REDIRECT: is the redirect URL defined above.

To obtain your client_id and client_secret, log in to your GitHub account and navigate to Settings > Developer Settings > OAuth Apps. For security reasons, GitHub requires the exact redirect URL you configure.

4. Sync GitHub Profile Data on login

You can listen to the DutchCodingCompany\FilamentSocialite\Events\Login event to sync GitHub profile data by creating a listener (e.g., SocialiteLoginListener) for this event:

namespace App\Listeners;

use App\Models\User;
use DutchCodingCompany\FilamentSocialite\Events\Login;
use Illuminate\Support\Arr;

class SocialiteLoginListener
{
    public function handle(Login $event): void
    {
        $socialiteUser = $event->socialiteUser;
        $user = $socialiteUser->getUser();

        if ($socialiteUser->provider === 'github') {
            if (! $user->bio && $bio = Arr::get($event->oauthUser->user ?? [], 'bio')) {
                $user->bio = $bio;
            }

            if (! $user->avatar_url && $avatarUrl = $event->oauthUser->getAvatar()) {
                $user->avatar_url = $avatarUrl;
            }

            if (! $user->github_url && $githubUrl = Arr::get($event->oauthUser->user ?? [], 'html_url')) {
                $user->github_url = $githubUrl;
            }

            if (! $user->twitter_url && $twitterUsername = Arr::get($event->oauthUser->user ?? [], 'twitter_username')) {
                $user->twitter_url = "https://x.com/$twitterUsername";
            }

            $user->save();
        }
    }
}

Explanation

This listener updates the user's local profile if values like bio, avatar_url, github_url, or twitter_url are not set.

5. Customizing the Register Page with Render Hooks

By default, the Filament plugin only adds social login buttons to the login page. To add them to the register page, use Filament’s Render Hook FilamentView::registerRenderHook:

FilamentView::registerRenderHook(
    PanelsRenderHook::AUTH_REGISTER_FORM_BEFORE,
    fn (): string => Blade::render('<div class="relative flex items-center justify-center text-center">
            <div class="absolute border-t border-gray-200 w-full h-px"></div>
            <p class="inline-block relative bg-white text-sm p-2 rounded-full font-medium text-gray-500 dark:bg-gray-800 dark:text-gray-100">
                Register via
            </p>
        </div>
        <x-filament-socialite::buttons :showDivider="false" />
        <div class="relative flex items-center justify-center text-center">
            <div class="absolute border-t border-gray-200 w-full h-px"></div>
            <p class="inline-block relative bg-white text-sm p-2 rounded-full font-medium text-gray-500 dark:bg-gray-800 dark:text-gray-100">
                Or register with email
            </p>
        </div>'),
);

Explanation

  • This hook inserts GitHub login buttons on the register page, before the form with some separator lines.
  • You can reuse <x-filament-socialite::buttons /> in any Blade view. If you want to update the associated view, you need to publish the vendor's views with php artisan vendor:publish command.

Filament Mastery - Filament Socialite Login with Github provider

Filament Mastery - Filament Socialite Register with Github provider

6. Final Thoughts

Filament Socialite makes it simple to add social login to your application. In just a few steps, you can offer GitHub login with custom logic for user creation and profile synchronization.

If you'd like a deeper dive or a video tutorial, feel free to leave a like!

Avatar of yebor974
yebor974
Freelance - French IT Engineer passionate about Laravel and Filament PHP, creating innovative solutions to simplify web development.
React
Share post

Stay ahead in the Filament Mastery adventure

Join our community of Filament PHP enthusiasts! Get exclusive tips, tutorials, and updates delivered straight to your inbox.