Social Login In Laravel With Socialite

Daniel Alabuja
9 min readJul 7, 2018

--

Social login is now an essential part of any site which performs user authentication. It saves the users a lot of time, as they won’t need to fill the whole form. They just sign up with their social account and next time they can log into the website by a single click.

Example of a social login page

The picture above shows a site that uses the social login for its sign up. In this tutorial, I will show you how to add multiple social providers to a Laravel app using Socialite a package built by Laravel for social authentication. Socialite currently supports authentication with Facebook, Twitter, LinkedIn, Google, GitHub, and Bitbucket. For this tutorial, we will add Facebook, Twitter, and Google Signups. The complete code can be found in Github.

I’m using Laravel 5.6 for this tutorial.

Migrations

If you look inside database/migrations of your project, you will notice that Laravel already comes with some migrations for creating the users’ and password resets tables.

We will use the migration for creating the users’ table in this example but you can use any migration of your choice. There are a few things I want us to make changes to before creating the users’ table.

A user created via OAuth will have a provider and we also need a provider_idwhich should be unique. With Facebook, there are cases where the user does not have an email set up but a phone number and thus the hash sent back by the callback will not have an email resulting to an error. To counter this, you can set the email field to nullable but because the aim of this tutorial is to make it possible for a user to signup using any of Facebook, Twitter or Google with the same email and retain their profile, we will not make the email field nullable. Also, when creating users via OAuth we will not be passing any passwords, therefore, we need to set the password field in the migration nullable.

Here, we are doing the following: adding provider and provider_id columns to the users’ table. We also make the password field in the users’ table nullable.

The up method in your migration should look like this:

public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email')->unique();
$table->string('image');
$table->string('provider');
$table->string('provider_id');
$table->string('password')->nullable();
$table->rememberToken();
$table->timestamps();
});
}

Next, on your terminal, run the migration with this command,

php artisan migrate

You need to add provider and provider_id to the list of fillable attributes in the model in our case User Model in app/User.php.

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

We will make use of the default Laravel authentication so that we can have a boilerplate for when the user login but we would make use of the social login for authentication and not the traditional register form. To make use of the default Laravel authentication, we need to run the command below:

php artisan make:auth

To start our local server, we need to run the command php artisan serve in our root directory, and visit the link given which in our case is http://127.0.0.1:8000. We will notice the link for both Log in and Register has been added to the nav and users can now register and login using the traditional registration form which isn’t our focus for this tutorial.

Installation and Configuration of Socialite

Run the following command in the root directory of your Laravel project to add the package to your project’s dependencies:

composer require laravel/socialite

Once the installation is complete, we need to register its service provider in config/app.php.

In the providers array, of config/app.php add

Laravel\Socialite\SocialiteServiceProvider::class,

In the aliases array of the same file, add

‘Socialite’ => Laravel\Socialite\Facades\Socialite::class,

Now Socialite is all set up and you are ready to implement social login in your Laravel apps.

  • Visit the link to register your app.
  • Click on the button “Add a New App”, a modal would show which you’re required to fill in the details.
  • You’ll be redirected to a page as shown below
  • Click on Basic under the Settings tab by the left of the page.
  • You need to fill in the details of App Domains in our case localhost.

Scroll down and click on the button “Add Platform” it would show a modal and you’re to select website.

  • Add the following to config/services.php
'facebook' => [
'client_id' => env('FACEBOOK_CLIENT_ID'),
'client_secret' => env('FACEBOOK_CLIENT_SECRET'),
'redirect' => env('FACEBOOK_URL'),
],
'twitter' => [
'client_id' => env('TWITTER_CLIENT_ID'),
'client_secret' => env('TWITTER_CLIENT_SECRET'),
'redirect' => env('TWITTER_URL'),
],
'google' => [
'client_id' => env('GOOGLE_CLIENT_ID'),
'client_secret' => env('GOOGLE_CLIENT_SECRET'),
'redirect' => env('GOOGLE_URL'),
],
  • Add the following to .env file
FACEBOOK_CLIENT_ID=
FACEBOOK_CLIENT_SECRET=
FACEBOOK_URL=http://localhost:8000/login/facebook/callback
TWITTER_CLIENT_ID=
TWITTER_CLIENT_SECRET=
TWITTER_URL=http://127.0.0.1:8000/login/twitter/callback
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_URL=http://localhost:8000/login/google/callback
  • At this point, copy the content of APP ID and App Secret from the settings dashboard into FACEBOOK_CLIENT_ID and FACEBOOK_CLIENT_SECRET respectively.
  • We can need a controller at this point. Run the following command in your project root directory
php artisan make:controller <NamofController>e.g php artisan make:controller SocialController
  • Add the following method to the controller created above
use Socialite;
class SocialController extends Controller
{
public function redirect($provider)
{
return Socialite::driver($provider)->redirect();
}
}

Note: The above method handles redirect from our site to the OAuth provider.

We need to call the route in routes/web.php

Route::get('login/{provider}', 'SocialController@redirect');

Note: The above route will be used for both Facebook and Google OAuth authentication to be integrated into this tutorial.

After successful login, it will redirect to the URL we have set as our callback URL, in our case http://localhost:8000/login/facebook/callback

The route that handles the callback is shown below:

Route::get('login/{provider}/callback','SocialController@Callback');

The Callback method below will read the incoming request and retrieve the user’s information from the provider.

public function Callback($provider)
{
$userSocial = Socialite::driver($provider)->user();
}

When the callback is done, we will want to perform some functions which include: log in the user to their profile if the user exists or create a new user. To handle that, the callback method above becomes as shown below:

public function Callback($provider){
$userSocial = Socialite::driver($provider)->stateless()->user();
$users = User::where(['email' => $userSocial->getEmail()])->first();
if($users){
Auth::login($users);
return redirect('/');
}else{
$user = User::create([
'name' => $userSocial->getName(),
'email' => $userSocial->getEmail(),
'image' => $userSocial->getAvatar(),
'provider_id' => $userSocial->getId(),
'provider' => $provider,
]);
return redirect()->route('home');
}
}

Your controller is now as shown below

use Socialite;
use Auth;
use App\User;
class SocialController extends Controller
{
public function redirect($provider)
{
"Line of Code"
}
public function Callback($provider)
{
"Lines of Code"
}
}

In both your registration and log in views, add this just below the closing tag of your form i.e. below the div containing the button.

resources/views/auth/register.blade.php and resources/views/auth/login.blade.php

<form>
<div class="form-group row">
<div class="col-md-6 offset-md-4">
<a href="{{ url('/login/facebook') }}" class="btn btn-facebook"> Facebook</a>

</div>
</div>
</form>

Check the home.blade.php view and add the following:

<p>My name: {{Auth::user()->name}}</p>
<p>My Email: {{Auth::user()->email}}</p>
<img alt="{{Auth::user()->name}}" src="{{Auth::user()->image}}"/>

The Auth Facade would return the currently logged in user’s name, email and image respectively.

After successful login, you would see your name, email, and avatar on the homepage.

We Have Successfully Implemented Facebook login to our Laravel app using Socialite.

Twitter Login

  • Visit the link to register your app.

Note: Twitter doesn’t make use of localhost. For more information about that, you can check this link. Also, you’ll need to add your phone number to be able to create an app in twitter. Visit the link to add a phone number to your account if you don’t already.

  • After creating the app, click on “Settings” tab to set the Privacy Policy URL and Terms of Service URL. Without setting both URL, the callback method would return an error as it wouldn’t be able to return the user’s email address.
  • After updating the settings, click, on “Permissions” tab to give access to your app to be able to return the user’s email.
  • At the point, click “Keys and Access Tokens” tab at the top to get API Key and API Secret into TWITTER_CLIENT_ID & TWITTER_CLIENT_SECRET respectively of your .env file.

We need to create a callback method in the controller created earlier on for Twitter because the AbstractProvider for the TwitterProvider does not implement stateless(). i.e. stateless OAuth is not possible with the TwitterProvider in the Laravel Socialite package out of the box.

public function TwitterCallback()
{
$twitterSocial = Socialite::driver('twitter')->user();
$users = User::where(['email' => $twitterSocial->getEmail()])->first();
if($users){
Auth::login($users);
return redirect('/home');
}else{
$user = User::firstOrCreate([
'name' => $twitterSocial->getName(),
'email' => $twitterSocial->getEmail(),
'image' => $twitterSocial->getAvatar(),
'provider_id' => $twitterSocial->getId(),
'provider' => 'twitter',
]);
return redirect()->route('home');
}
}

The method above handles the callback for twitter only.

Call the method on your routes as shown below:

Route::get('login/twitter/callback', 'SocialController@TwitterCallback');

Now I would add a link to resources/views/auth/login.blade.php & resources/views/auth/register.blade.php.

<a href="{{ url('/login/twitter') }}" class="btn btn-twitter"> Twitter</a>

Note: The routes and controller have already been done earlier on.

At login using Twitter, the user is redirected to the page shown below if he is logged in to Twitter on the browser else to another page.

When we authorize the app, it would create the user if the email is not registered then it redirects to the home page with the details of the user or just redirects to the homepage for a register email address.

We Have Successfully Implemented Twitter login to our Laravel app using Socialite.

Google Login

  • Visit the link to register your app
  • Click on “select a project” in the left side of navigation which would show a modal where you’re expected to create a project from

After the app is created, the redirects to the dashboard where we’re to Enable Apis and Services by following the link.

  • It redirects to the API library dashboard where you’re to select Google+ API under the Social section of the same page.
  • The social section looks as shown below
  • It redirects to a page where you enable the Google+ API to our Laravel app
  • You’ve successfully enabled Google+ API to your app, and it will redirect to another page but click on Credentials on the left side of navigation and select OAuth consent screen tab and fill out the details here.
  • Now we need to create credentials for your app. Click credentials in left side navigation and select Credentials. In the drop-down select OAuth client ID.
  • In the OAuth client ID screen, select the type of application, and fill the details,
  • Copy the content of client id and client secret to GOOGLE_CLIENT_ID & GOOGLE_CLIENT_SECRET respectively of your .env file.

Now we would add a link to resources/views/auth/login.blade.php & resources/views/auth/register.blade.php.

<a href="{{ url('/login/google') }}" class="btn btn-google-plus"> Google</a>

Note: The routes and controller have already been done earlier on.

Google Social Login Page

If not logged in, we would be redirected to the page above.

When we authorize the app, it would create the user if the email is not registered then it redirects to the home page with the details of the user or just redirects to the home page for a registered email address.

We Have Successfully Implemented Google + login to our Laravel app using Socialite.

Conclusion

We have successfully implemented social login in Facebook, Twitter, and Google using Socialite — The official package provided by Laravel for OAuth authentication.

--

--