loading...

Social Authentication With Laravel

jeremiahiro profile image JEREMIAH IRO ・3 min read

laravel socialite

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 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 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, Twitter, Github, and Google

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

<?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.

Posted on by:

jeremiahiro profile

JEREMIAH IRO

@jeremiahiro

Business Management Graduate Turned Web Developer

Discussion

pic
Editor guide