Table of Contents
Laravel provides a clean convenient way to integrate social login to your existing project easily using Laravel Socialite.
Although, this package is not pre-installed in laravel. The steps are quite easy as we’ll go through step by step guide to implement social login from scratch.
However, Laravel Socialite supports authentication only for the following social login providers:
- GitHub
- GitLab
- Bitbucket
Start with a Fresh Installation of Laravel
Let’s start with a fresh installation of Laravel 7 cause at the time of writing this post, Laravel 7 was the latest version of laravel. So, We will start by installing and launching a new laravel project using the following command:
composer create-project --prefer-dist laravel/laravel social-login
Configure and Migrate Database
Create a database and configure database credentials in the .env file at the root of your laravel project.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=yourdatabase
DB_USERNAME=user
DB_PASSWORD=password
Now before you migrate, if you get an error like Specified key was too long
. Then, you might want to insert this code into your AppServiceProvider.php
. However, You will not have this problem if you’re using MySQL 5.7.7+ or MariaDB 10.2.2+.
<?php
use Illuminate\Support\Facades\Schema;
//..
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
// Add This -------------
Schema::defaultStringLength(191);
}
Then, run the following command.
php artisan migrate
Install laravel/ui Package and Scaffold Basic Authentication
This package provides a quick and easy way to scaffold all of the routes and views you need for authentication. So, we’ll have to install this package as well.
composer require laravel/ui
php artisan ui bootstrap --auth
npm install
npm run dev
Install and configure Laravel/socialite
composer require laravel/socialite
After that, go to app/config.php and paste the code below for Google and Facebook or other providers you want.
'google' => [
'client_id' => env('GOOGLE_CLIENT_ID'),
'client_secret' => env('GOOGLE_CLIENT_SECRET'),
'redirect' => env('GOOGLE_REDIRECT'),
],
'facebook' => [
'client_id' => env('FB_CLIENT_ID'),
'client_secret' => env('FB_CLIENT_SECRET'),
'redirect' => env('FB_REDIRECT'),
],
And, the credentials should be in the .env file should look like this.
GOOGLE_CLIENT_ID=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
GOOGLE_CLIENT_SECRET=XXXXXXXXXXXXXXXXXXXXXXXX
GOOGLE_REDIRECT=http://domain.com/google/callback
Redirect Users to the Google/Facebook Login Portal
For this, let’s define a route in routes/web.php and link to the LoginController.php to redirect the user to the selected provider login portal.
Route::get('redirect/{driver}', 'Auth\LoginController@redirectToProvider');
Now add this function to your app/Http/Controllers/Auth/LoginController.php:
use Socialite;
// ...
/**
* Redirect the user to the provider authentication page.
*
* @return \Illuminate\Http\Response
*/
public function redirectToProvider($driver)
{
return Socialite::driver($driver)->redirect();
}
Then, you might want to add an anchor link on your resources/views/auth/login.blade.php or register.blade.php:
<a href="{{ url('redirect/google') }}">Google Login</a>
// or
<a href="{{ url('redirect/facebook') }}">Facebok Login</a>
Handle Callback from Users
After redirecting the user to the social login portal, if the user successfully signs into Google or from any other supported providers by Socialite, then the user will be redirected to the given callback URL you defined in your .env file.
But first, we define a callback route in routes/web.php
Route::get('{driver}/callback', 'Auth\LoginController@handleProviderCallback');
Now, we have created a new method to handle the logic for login in Auth/LoginController.php: inside the HTTP folder.
use App\User;
// ...
/**
* Obtain the user information from provider.
*
* @return \Illuminate\Http\Response
*/
public function handleProviderCallback($driver)
{
try {
$user = Socialite::driver($driver)->user();
} catch (\Exception $e) {
return redirect()->route('login');
}
$existingUser = User::where('email', $user->getEmail())->first();
if ($existingUser) {
auth()->login($existingUser, true);
} else {
$newUser = new User;
$newUser->provider_name = $driver;
$newUser->provider_id = $user->getId();
$newUser->name = $user->getName();
$newUser->email = $user->getEmail();
// we set email_verified_at because the user's email is already veridied by social login portal
$newUser->email_verified_at = now();
// you can also get avatar, so create avatar column in database it you want to save profile image
// $newUser->avatar = $user->getAvatar();
$newUser->save();
auth()->login($newUser, true);
}
return redirect($this->redirectPath());
}
In the handleProviderCallback method above:
- We first try to get the user from Socialite, if it fails then we redirect to the login page.
- Then, we check our database for matching users by email provided.
- Check if the user exists, if so then we will proceed to log in the user.
- If not, then we will create a new User and log in to them.
Okay, that’s all, you have successfully implemented Laravel Socialite in your project.
Finally, if you want to add other login providers then just add credentials in the .env file and enable them config/auth.php
by adding another array of providers.
Nice and very helpful topics.