Social Authentication With Laravel
Tags: laravel, socialite, auth, login
Published: 2020-09-11 08:22:42

---
title: Social Authentication With Laravel
published: true
description: Integrate Social Login in Your Laravel Project
tags: Laravel, Socialite, Auth, Login
main_image: ![laravel socialite](https://dev-to-uploads.s3.amazonaws.com/i/itj6hh0p1p5iikwpixo4.jpg)
---

![laravel socialite](https://dev-to-uploads.s3.amazonaws.com/i/itj6hh0p1p5iikwpixo4.jpg)

The use of social accounts for signup and sign is gradually becoming the new norm as it makes the authentication process very easy without the rigorous process of filling forms and verifying email.

In this tutorial, I walk you through on how to use [Laravel Socialite](https://laravel.com/docs/8.x/socialite) for authentication.

I am going to integrate social login in this tutorial; this is not a beginner's guide so I'm assuming you have your Laravel app setup, the [Laravel Doc](https://laravel.com/docs/8.x) is a good guide for that.

Let's get started.

### Prerequisite
You need to create a new app for your socials so as to get an `API ID` and `SECRET`

Use the guide to creating a social app for [Facebook](https://developers.facebook.com/docs/apps), [Twitter](https://developer.twitter.com/en/apps), [Github](https://docs.github.com/en/developers/apps/creating-an-oauth-app), and [Google](https://console.developers.google.com/apis/dashboard?project=my-test-project-265215)

### Installation
In your Laravel App run the following command on the terminal
```
composer require laravel/socialite
```

Afterward, head over to `config/services.php` and update the variables

```
// Facebook Config
'facebook' => [
    'client_id' => env('FACEBOOK_CLIENT_ID'),  // Your Facebook App ID
    'client_secret' => env('FACEBOOK_CLIENT_SECRET'), // Your Facebook App Secret
    'redirect' => env('FACEBOOK_CALLBACK_URL')
],

// Twitter Config
'twitter' => [
    'client_id' => env('TWITTER_CLIENT_ID'),  // Your Twitter Client ID
    'client_secret' => env('TWITTER_CLIENT_SECRET'), // Your Twitter Client Secret
    'redirect' => env('TWITTER_CALLBACK_URL'),
],

// Github Config
'github' => [
    'client_id' => env('GITHUB_CLIENT_ID'), // Your GitHub Client ID
    'client_secret' => env('GITHUB_CLIENT_SECRET'), // Your GitHub Client Secret
    'redirect' => env('GITHUB_CALLBACK_URL'),
],

// Google Config
'google' => [
    'client_id' => env('GOOGLE_CLIENT_ID'), // Your Google Client ID
    'client_secret' => env('GOOGLE_CLIENT_SECRET'), // Your Google Client Secret
    'redirect' => env('GOOGLE_CALLBACK_URL'),
],
```
Update your `.env` to have the following
```
FACEBOOK_CLIENT_ID=********
FACEBOOK_CLIENT_SECRET=********
FACEBOOK_CALLBACK_URL=https://app-url/login/facebook/callback

TWITTER_CLIENT_ID=********
TWITTER_CLIENT_SECRET=********
TWITTER_CALLBACK_URL=https://app-url/login/twitter/callback

GITHUB_CLIENT_ID=********
GITHUB_CLIENT_SECRET=********
GITHUB_CALLBACK_URL=https://app-url/login/github/callback

GOOGLE_CLIENT_ID=********
GOOGLE_CLIENT_SECRET=********
GOOGLE_CALLBACK_URL=https://app-url/login/google/callback
```

### Database/Migration
Modify the user table and make the `email` and `password` columns nullable.

```
$table->string('email')->unique()->nullable();
$table->string('password')->nullable();
```
Add the following columns for social account

```
$table->string('provider', 20)->nullable();
$table->string('provider_id')->nullable();
$table->string('access_token')->nullable();
```

You can not run your migration from the command line
```
php artisan migrate
```

### Routing
We need two routes for this, one for redirecting to the provider and another for receiving a callback from the provider after authentication

Add the following routes in the `routes/web.php`
```
Route::get('login/{provider}', 'AuthLoginController@redirectToProvider')->name('login.social');

Route::get('login/{provider}/callback','AuthLoginController@handleProviderCallback');
```
Next, we need to update the `LoginController`.
`Socialite` will be accessed using the [Socialite Facade](https://laravel.com/docs/5.5/facades)

```
<?php

namespace App\Http\Controllers\Auth;

use Auth;
use Socialite;
use Carbon\Carbon;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;

class LoginController extends Controller
{
    /**
     * Redirect the user to the social authentication page.
     * this includes GitHub, Twitter, Facebook, and Google
     *
     * @return Response
    */
    public function redirectToProvider($provider)
    {
         return Socialite::driver($provider)->redirect();
    }

    /**
     * Obtain the user information from Social Account.
     *
     * @return Response
    */
    public function handleProviderCallback($provider)
    {
        try {
            $providerUser= Socialite::driver($provider)->user();
        } catch (Exception $e) {
            return $this->sendFailedResponse($e->getMessage());
        }

        if ($user->email != null) {
            $authUser = $this->findOrCreateUser($providerUser, $provider);
            Auth::login($authUser, true);
            return redirect()->intended('/');
        }
        return $this->sendFailedResponse();
    }


   /**
     * If a user has registered before using social auth, return the user
     * else, create a new user object.
     * @param  $providerUser Socialite user object
     * @param $provider Social auth provider
     * @return  User
     */
   public function findOrCreateUser($providerUser, $provider)
   {
        $authUser = User::where('email', $providerUser->email)->first();
        if ($authUser) {
            return $authUser;
        } else {
            $user = User::create([
               'name'              => $providerUser->name,
               'email'             => $providerUser->email,
               'provider_id'       => $providerUser->id,
               'access_token'      => $providerUser->token,
               'provider_name'     => $provider,
               'email_verified_at' => Carbon::now()->format('Y-m-d H:i:s');
               ]);
           }
           return $user;
       }
   }

    /**
      * Send a failed response with a msg
      *
      * @param null $msg
      * @return \Illuminate\Http\RedirectResponse
    */
    protected function sendFailedResponse($message = null)
    {
         return redirect()->route('login')
             ->withError(['message' => $message ?: 'Unable to login, try with another provider to login.']);
    }
```

And lastly, in your `blade` file, you can add the various links to your registration and login form
```
...
  href="{{ route('login.social', 'facebook') }}" 

  href="{{ route('login.social', 'twitter') }}" 

  href="{{ route('login.social', 'github') }}" 

  href="{{ route('login.social', 'google') }}"
...
```

### In Conclusion
We have successfully added social login to our Laravel app.