Facebook, GitHub login implementation with Laravel Socialite

Providing users the ability to signup / signin with their social accounts is a great idea, it’s fast & secure also.

Laravel has a first-party package called Laravel Socialite which provides an easy way to implement social signin / signup with popular platforms like Facebook, Twitter, Google, LinkedIn, Github, etc.

In this post, I’ll implement Facebook & GitHub only.

So, I’ll install a fresh Laravel project with Jetstream,

laravel new socialite

cd socialite

composer require laravel/jetstream

php artisan jetstream:install livewire

npm install

npm run build

create a Database and setup the .env file

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=socialite
DB_USERNAME=root
DB_PASSWORD=password
.env

Then, Migrate the database.

php artisan migrate

Start the application server, You’ll see a homepage with Login & Register links.

laravel jetstreams home

The default login page is fine, But I’ll add two extra links that’s something look like Buttons. So, users can process social login from here.

<a href="{{ url('/auth/github/redirect') }}"
   class="py-2 px-4 max-w-md flex justify-center items-center bg-gray-800 hover:bg-gray-700 focus:ring-gray-500 focus:ring-offset-gray-200 text-white w-full transition ease-in duration-200 text-center text-base font-semibold shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 rounded-lg">
    <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor"
         class="bi bi-github mr-2" viewBox="0 0 16 16">
        <path
            d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.012 8.012 0 0 0 16 8c0-4.42-3.58-8-8-8z"/>
    </svg>
    Continue with GitHub
</a>

<a href="{{ url('/auth/facebook/redirect') }}"
   class="py-2 px-4 max-w-md flex justify-center items-center bg-blue-700 hover:bg-blue-800 focus:ring-blue-500 focus:ring-offset-blue-200 text-white w-full transition ease-in duration-200 text-center text-base font-semibold shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 rounded-lg">
    <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor"
         class="bi bi-facebook mr-2" viewBox="0 0 16 16">
        <path
            d="M16 8.049c0-4.446-3.582-8.05-8-8.05C3.58 0-.002 3.603-.002 8.05c0 4.017 2.926 7.347 6.75 7.951v-5.625h-2.03V8.05H6.75V6.275c0-2.017 1.195-3.131 3.022-3.131.876 0 1.791.157 1.791.157v1.98h-1.009c-.993 0-1.303.621-1.303 1.258v1.51h2.218l-.354 2.326H9.25V16c3.824-.604 6.75-3.934 6.75-7.951z"/>
    </svg>
    Continue with Facebook
</a>
login.blade.php
laravel social login

Our UI parts are done.


Install the Laravel Socialite package.

composer require laravel/socialite

Now, we need to add some extra columns in the users’ table. open the users’ migration file and add these extra columns,

$table->string( 'social_id' )->unique()->nullable();
$table->text( 'social_token' )->nullable();
$table->enum( 'login_type', [ 'email', 'github', 'facebook' ] )
      ->default( 'email' );
PHP

Make sure the password column is nullable,

$table->string( 'password' )->nullable();
PHP

Run migration

php artisan migrate:fresh

Update $fillable property in the User model.

protected $fillable = [
    'social_id',
    'social_token',
    'name',
    'email',
    'password',
    'login_type'
];
App/Models/User.php


GitHub

First, go to config/services.php and add this configuration,

'github'   => [
    'client_id'     => env( 'GITHUB_CLIENT_ID' ),
    'client_secret' => env( 'GITHUB_CLIENT_SECRET' ),
    'redirect'      => 'http://localhost:8000/auth/github/callback',
 ],
config/services.php

Here, I hard-coded the redirect URL, but it’s a good idea to manage it via .env or concatenating with APP_URL

'github'   => [
    'client_id'     => env( 'GITHUB_CLIENT_ID' ),
    'client_secret' => env( 'GITHUB_CLIENT_SECRET' ),
    'redirect'      => env( 'APP_URL' ) . '/auth/github/callback',
 ],
PHP

Next, need to create an OAuth on GitHub.

github oauth apps
create oauth app github

after creating an OAuth app, you’ll find the Client ID & Client Secret ( you need to generate a client secret) from the app details screen.

github oauth app client secrets

Copy the Client ID and Client Secret, put it .env file

GITHUB_CLIENT_ID=CLIENT_ID_HERE
GITHUB_CLIENT_SECRET=CLIENT_SECRET_HERE
.env

Create a controller called GithubController. I’ll define two methods here, One is for redirect, other for callback.

<?php

namespace App\Http\Controllers;

use App\Models\User;
use Auth;
use Laravel\Socialite\Facades\Socialite;

class GithubController extends Controller {

    public function redirect() {
        return Socialite::driver( 'github' )->redirect();
    }

    public function callback() {
        $githubUser = Socialite::driver( 'github' )->user();

        $user = User::createOrFirst( [
            'email' => $githubUser->email
        ], [
            'social_id'    => $githubUser->id,
            'name'         => $githubUser->name,
            'social_token' => $githubUser->token,
            'login_type'   => 'github'
        ] );

        // if user is already existed, we need to check login_type.
        if ( $user->login_type !== 'github' ) {
            return redirect( 'login' )
                    ->withErrors( [ "email" => 
                      "Your email already used to manage another account !" ] 
                      );
        }

        Auth::login( $user );

        return redirect( '/dashboard' );
    }

}
GithubController.php

Define two routes, One for redirect & other for callback,

Route::prefix( '/auth' )->group( function () {

    Route::get( '/github/redirect', [ GithubController::class, 'redirect' ] );
    Route::get( '/github/callback', [ GithubController::class, 'callback' ] );
    
} );
web.php

Facebook

The solution is the same as Github.

'facebook' => [
    'client_id'     => env( 'FACEBOOK_CLIENT_ID' ),
    'client_secret' => env( 'FACEBOOK_CLIENT_SECRET' ),
    'redirect'      => env( 'APP_URL' ) . '/auth/facebook/callback'
],
config/services.php

Go to the Facebook developers’ website and create an app.

facebook developers app
create facebook developer app
create facebook developer app

create a test app inside the newly created app.

create facebook developer test app

Inside the test app, Under App Settings | Basic, you’ll find the App ID & App secret

facebook developer test app credentials

Copy & put them in .env file

FACEBOOK_CLIENT_ID=APP_ID_HERE
FACEBOOK_CLIENT_SECRET=APP_SECRET_HERE
.env

Under App Settings | Advanced, you need to insert a callback URL in the Share Redirect Domain Allow List.

set redirect domain

At the end, define routes and create a controller.

Route::prefix( '/auth' )->group( function () {
    Route::get( '/github/redirect', [ GithubController::class, 'redirect' ] );
    Route::get( '/github/callback', [ GithubController::class, 'callback' ] );

    Route::get( '/facebook/redirect', [ FacebookController::class, 'redirect' ] );
    Route::get( '/facebook/callback', [ FacebookController::class, 'callback' ] );
} );
web.php
<?php

namespace App\Http\Controllers;

use App\Models\User;
use Auth;
use Laravel\Socialite\Facades\Socialite;

class FacebookController extends Controller {

    public function redirect() {
        return Socialite::driver( 'facebook' )->redirect();
    }

    public function callback() {
        $facebookUser = Socialite::driver( 'facebook' )->user();

        $user = User::createOrFirst( [
            'email' => $facebookUser->email,
        ], [
            'social_id'    => $facebookUser->id,
            'name'         => $facebookUser->name,
            'social_token' => $facebookUser->token,
            'login_type'   => 'facebook'
        ] );

        if ( $user->login_type !== 'facebook' ) {
            return redirect( 'login' )
                    ->withErrors( [ "email" => 
                        "Your email already used to manage another account !" 
                        ] );
        }

        Auth::login( $user );

        return redirect( '/dashboard' );
    }

}
FacebookController.php

Thats it!

facebook social login

Email Login

In this example, I’m using Jetstream and need to update the authentication process. The authentication portions of Jetstream are powered by Laravel Fortify

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Laravel\Fortify\Fortify;


/**
 * Bootstrap any application services.
 */
public function boot(): void {
    
    // ...

    Fortify::authenticateUsing( function ( Request $request ) {

    $user = User::where( 'email', $request->email )->first();
  
    if ( $user && Hash::check( $request->password, $user->password ) 
              && $user->login_type === 'email' ) {
            return $user;
      }
      
  } );
}
JetstreamServiceProvider.php

You’ll find the complete source code here.

Thanks.

Istiaq Nirab

A highly skilled and proficient WordPress developer with over Three years of professional experience in all aspects of WordPress website creation, including design, plug-ins, and implementation. Results-driven individual contributor with a successful track record in exceeding expectations for web development initiatives

More Reading

Post navigation

Leave a Comment

Leave a Reply

Your email address will not be published. Required fields are marked *