Social Login with Laravel Socialite (Google , facebook , github)
Tags: laravel, backend
Published: 2024-04-06 13:34:15

Laravel Socialite is an official Laravel package that provides a simple and convenient way to authenticate users with third-party services, such as Facebook, GitHub, Google, Twitter, and more. It abstracts the complexities of the OAuth authentication process and provides a unified API for authentication with various social platforms.

create a new Laravel project via Composer's create-project
`$ composer create-project laravel/laravel:^10.0 SocialLogin
`
**Step 1: Install Laravel Socialite**
Start by installing Laravel Socialite via Composer. Open your terminal and navigate to your Laravel project directory, then run the following command:
`composer require laravel/socialite`

**Step 2: [Socialite Providers](https://socialiteproviders.com/about/)**
SocialiteProviders is a collection of OAuth 1 & 2 packages that extend Laravel Socialite.
The Observer Pattern is used by the Manager package to extend Socialite.
This allows numerous providers to be used in addition to the ones provided by Laravel Socialite

**Google ,facebook ,github provider**
1:
`composer require socialiteproviders/google
`
`composer require socialiteproviders/facebook
`
`composer require socialiteproviders/github
`
2:Add configuration to config/services.php

```
'google' => [    
  'client_id' => env('GOOGLE_CLIENT_ID'),  
  'client_secret' => env('GOOGLE_CLIENT_SECRET'),  
  'redirect' => 'auth/google/callback'
],
'facebook' => [    
  'client_id' => env('FACEBOOK_CLIENT_ID'),  
  'client_secret' => env('FACEBOOK_CLIENT_SECRET'),  
  'redirect' => env('FACEBOOK_REDIRECT_URI') 
],
'github' => [    
  'client_id' => env('GITHUB_CLIENT_ID'),  
  'client_secret' => env('GITHUB_CLIENT_SECRET'),  
  'redirect' => env('GITHUB_REDIRECT_URI') 
],

```

3:Configure google API credentials

- [google](https://console.cloud.google.com/welcome)
- [facebook](https://developers.facebook.com/)
- [github](https://github.com/settings/developers)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/el7xmx1mq38xx4qc0c2z.PNG)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/anmfr53j68csys5kk6ph.PNG)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zph6zmrtp7kyy51fekog.PNG)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w97o3u5xiugxfhsx20ln.PNG)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iafx1rfmhyvjpvuy2o0t.PNG)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ofs2vp9iaks2136dpcf9.PNG)

click 
sava and continue
back to dashboard


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eb5a5ux48xpzmqjjkzhd.PNG)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1y0iu7pib80cq4b4fl2h.PNG)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1nra0dv1rnwxk7p5pfmx.PNG)



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/12fp791dcmpdwzziqxfg.PNG)


4:add your client id and secret in env 
```
GOOGLE_CLIENT_ID=##########
GOOGLE_CLIENT_SECRET=##########
GOOGLE_REDIRECT_URI=##########

GITHUB_CLIENT_ID=##########
GITHUB_CLIENT_SECRET=##########
GITHUB_REDIRECT_URI=##########

FACEBOOK_CLIENT_ID=##########
FACEBOOK_CLIENT_SECRET=##########
FACEBOOK_REDIRECT_URI=##########

```

5:create Social Login Controller
`php artisan make:Controller Auth/SocialLoginController
`
6:web

```

Route::get('login', [LoginController::class, 'loginCreate']);
Route::post('login', [LoginController::class, 'login'])->name('login');

Route::get('auth/{provider}/redirect', [SocialLoginController::class , 'redirect'])->name('auth.socialite.redirect');
Route::get('auth/{provider}/callback', [SocialLoginController::class , 'callback'])->name('auth.socialite.callback');

Route::middleware("auth")->group(function () {
    Route::get('/', function () {
        return 'welcome ';
    })->name('home');
});

```

7:update user table
`php artisan make:migration add_social_provider_columns_to_users_table
`

```
   public function up(): void
    {
        Schema::table('users', function (Blueprint $table) {
            $table->string('provider_name')->nullable();
            $table->string('provider_id')->nullable();
            $table->string('provider_token',500)->nullable();
        });
    }

    
    public function down(): void
    {
        Schema::table('users', function (Blueprint $table) {
            $table->dropColumn(['provider_name', 'provider_id', 'provider_token']);
        });
    }
```
8:update User model

```

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;

    protected $fillable = [
        'name',
        'email',
        'password',
        'provider_name',
        'provider_id',
    ];

 
    protected $hidden = [
        'password',
        'remember_token',
        'provider_token'

    ];

    
    protected $casts = [
        'email_verified_at' => 'datetime',
        'password' => 'hashed',
    ];

    public function setProviderTokenAttribute($value){
        return $this->attributes['provider_token'] = Crypt::crypt($value);
    }

    public function getProviderTokenAttribute($value)
    {
        return Crypt::decrypt($value);
    }
}

```

9:Social Login Controller

```
<?php

namespace App\Http\Controllers\Auth;

use App\Models\User;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Laravel\Socialite\Facades\Socialite;
use Nette\Utils\Random;

class SocialLoginController extends Controller
{
    public function redirect($provider)
    {
        return Socialite::driver($provider)->redirect();
    }

    public function callback($provider)
    {
        $user = Socialite::driver($provider)->user();
        $existingUser = User::where('email', $user->email)->first();
        // dd($user);
        if ($existingUser) {
            Auth::login($existingUser);
        } else {

            User::create([
                'name'          => $user->name,
                'email'         => $user->email,
                'password'      => Hash::make(Str::random(8)),
                'provider_name' => $provider,
                'provider_id'   => $user->id,
                'provider_token' => $user->token
            ]);
        }
        return view('welcome');
    }
}

```

10:login.blade.php

```
  <section class="vh-100">
    <div class="container-fluid h-custom">
        <div class="row d-flex justify-content-center align-items-center h-100">
            <div class="col-md-9 col-lg-6 col-xl-5">
                <img src="https://mdbcdn.b-cdn.net/img/Photos/new-templates/bootstrap-login-form/draw2.webp" class="img-fluid" alt="Sample image">
            </div>
            <div class="col-md-8 col-lg-6 col-xl-4 offset-xl-1">
                <div class="d-flex flex-row align-items-center justify-content-center justify-content-lg-start row mt-5">
                    <div class="col-5">
                        <p class="lead fw-normal mb-0 me-3">Sign in with</p>
                    </div>

                    <div class="col-2">
                        <a href="{{route('auth.socialite.redirect','google')}}">
                            <i class="fab fa-google"></i>
                        </a>
                    </div>

                    <div class="col-2">
                        <a href="{{route('auth.socialite.redirect','facebook')}}">
                            <i class="fab fa-facebook"></i>
                        </a>
                    </div>

                    <div class="col-2">
                        <a href="{{route('auth.socialite.redirect','github')}}">
                            <i class="fab fa-github"></i>
                        </a>
                    </div>
                </div>

                <div class="divider d-flex align-items-center my-4">
                    <p class="text-center fw-bold mx-3 mb-0">Or</p>
                </div>

                <form action="{{route('login')}}" method="POST">
                    @csrf
                    <!-- Email input -->
                    <div class="form-outline mb-4">
                        <input type="email" name="email" id="form3Example3" class="form-control form-control-lg" placeholder="Enter a valid email address" />
                    </div>

                    <!-- Password input -->
                    <div class="form-outline mb-3">
                        <input type="password" name="password" id="form3Example4" class="form-control form-control-lg" placeholder="Enter password" />
                    </div>

                    <div class="d-flex justify-content-between align-items-center">
                        <!-- Checkbox -->
                        <div class="form-check mb-0">
                            <input class="form-check-input me-2" type="checkbox" value="" id="form2Example3" />
                            <label class="form-check-label" for="form2Example3">
                                Remember me
                            </label>
                        </div>
                        <a href="#!" class="text-body">Forgot password?</a>
                    </div>

                    <div class="text-center text-lg-start mt-4 pt-2">
                        <button type="submit" class="btn btn-primary btn-lg" style="padding-left: 2.5rem; padding-right: 2.5rem;">Login</button>
                        <p class="small fw-bold mt-2 pt-1 mb-0">Don't have an account? <a href="#!" class="link-danger">Register</a></p>
                    </div>

                </form>
            </div>

        </div>
    </div>

</section>


```