Social authentication with Laravel Socialite

https://www.hibit.dev/images/social/2022/preview/laravel_socialite.png

Social login is now an essential part of any site which performs user authentication. It does not need to replace the standard form based authentication, quite the contrary, social login complements it. Login with social accounts is a straightforward process and 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 they can log into the website with just a few clicks.

OAuth is an open standard protocol for access delegation, commonly used as a way for internet users to grant websites or applications access to their information on other websites but without giving them the passwords. Laravel Socialite package provides a simple, fluent interface to authenticate with OAuth providers. It currently supports authentication via Facebook, Twitter, LinkedIn, Google, GitHub, GitLab and Bitbucket.

Prerequisites

A Laravel project is required to use Socialite package. Take a look on how to create your first Laravel project, if you don’t have any yet. The latest stable and compatible version is recommended to be installed for the both: framework and PHP.

Additionally, we recommend reading about the OAuth 2.0 protocol: understanding OAuth 2.0 and how it works.

Installation

To get started with Socialite, use the Composer package manager to add the package to your project’s dependencies:

composer require laravel/socialite

Registering with OAuth providers

Before implementing and using Socialite, you will need to generate credentials for OAuth providers your application want to operate with. Typically, these credentials may be retrieved by creating a developer application within the service you will be authenticating with.

Detailed explanation on how to retrieve credentials for different services can be found below:

Configuring your application

Credentials generated in the step above should be placed in your application’s config/services.php configuration file. Depending on the providers you want to use, credentials are defined with one of the following keys : facebook, twitter-oauth-2, linkedin, google, github, gitlab or bitbucket.

'google' => [
'client_id' => env('OAUTH_GOOGLE_CLIENT_ID'),
'client_secret' => env('OAUTH_GOOGLE_CLIENT_SECRET'),
'redirect' => 'https://your-domain.com/callback-url',
],

That’s an example of definition of Google OAuth credentials in config/services.php configuration file.

Define environment variables

Environment variables provide another way to specify configuration options and credentials. As you can see, the definition of credentials in config/services.php is using environment variables and it means that you need to define them in your .env file:

OAUTH_GOOGLE_CLIENT_ID=your_google_client_id
OAUTH_GOOGLE_CLIENT_SECRET=your_google_client_secret

Feel free to use any variable name and replace values with credentials generated within the OAuth provider.

Specify Socialite routes

Any provider defined with Socialite need two routes:

Route::get('/google', 'OAuthGoogleController@redirect')->name('oauth.google');
Route::get('/google-callback', 'OAuthGoogleController@callback');

Define both routes in the project routes/web.php file with desired options (prefixes, names, middleware, etc…).

Preparing your database

Once the user has been retrieved from the OAuth provider, you may determine if the user exists in your application’s database and authenticate the user. If the user does not exist in your application’s database, you will typically create a new record in your database to represent the user. OAuth callbacks include a string that represents a unique identifier for the user on the OAuth platform.

In case of using MySQL database, a new varchar column can be added to the users table. It will contain OAuth identifier and help us to find the user in future queries, i.e., facebook_id, twitter_id, google_id, etc... You may want to save user token, refresh token and token expiration date too. Everything depends on the use case.

Implementing Socialite controller

We’ve previously configured two routes for the OAuth provider and both routes are pointing to the same controller. Socialite helps to abstract the complicated OAuth logic making the implementation quite standard, with slight differences for different providers. A template has been defined and it can be used for all available OAuth2 providers changing the class constant and completing TODOs that depends on your application.

<?php namespace App\\Controllers;

use Illuminate\\Http\\Request;
use Illuminate\\Http\\RedirectResponse;

use Laravel\\Socialite\\Facades\\Socialite;
use Laravel\\Socialite\\Two\\User as SocialUser;

class OAuthGoogleController
{
// facebook, twitter twitter-oauth-2, linkedin, google, github, gitlab, bitbucket
const OAUTH_PROVIDER = 'google';

public function redirect(): RedirectResponse
{
return Socialite::driver(self::OAUTH_PROVIDER)->redirect();
}

public function callback(Request $request): RedirectResponse
{
/** @var SocialUser $socialUser */
$socialUser = Socialite::driver(self::OAUTH_PROVIDER)->user();

if ($socialUser->getEmail() === null) {
// TODO Missing email, redirect to manual registration page
}

try {
// TODO Get user from database using ID or email address
// TODO Throw UserNotFoundException if user does not exist
// TODO Update user attributes (if needed)
} catch (UserNotFoundException $e) {
// TODO Create new user record in the database
} finally {
// TODO Authenticate existing or new created user in the system
}

// TODO redirect authenticated user
}
}

First let’s check what kind of information social user variable contains:

$socialUser->getId() // User identifier from OAuth provider
$socialUser->getNickname() // User nickname or null
$socialUser->getName() // User name concatenated with surname in some cases
$socialUser->getEmail() // User email address
$socialUser->getAvatar() // User avatar URL

Additional information can be gathered for Google OAuth users:

$socialUser['email_verified'] // User email verification flag (boolean)

Generally, for OAuth2 providers, token information is available too:

$socialUser->token
$socialUser->refreshToken
$socialUser->expiresIn

As you can see it’s very easy to setup any provider and the code for all of them is quite similar.

Conclusion

Login with social accounts is a straightforward process and at the same time it improves the user experience. Officially Socialite plugin only supports popular platforms for OAuth but you can find non-official implementations of other platforms too.

Laravel News Links