Laravel — Implementing Social Auth for API (via mobile app) with Socialite & Passport

John stavropoulos
3 min readApr 26, 2021

--

While I was developing an API for a mobile app, I faced the issue of how I could implement a social authentication (Facebook, Google) between our mobile app and our API.

I knew about Laravel’s Socialite package for implementing that in the web (with redirects and callbacks…) but I was not familiar of doing that using an API.

After some search and testing I figured out the best way of doing this, with best practises and security in mind.

This is a clear and complete implementation flow and example, of how I achieved that easily with Laravel, Laravel Passport and Laravel Socialite.

TL;DR

The flow is simple:

  • In the mobile app, you use the specific SDK’s for user authentication.
  • Using the SDK’s you get an access token for that user.
  • You send a request to the mobile app’s API (login route) with the access token in a parameter.
  • You get the access token and re-authenticate it in the backend using Socialite package:
Socialite::driver('facebook')->userFromToken($access_token);
  • If the access_token exists and is correct, you get the user’s info (provider’s user), and continue your logic (e.g create or login the user).

Complete Example (Laravel 8)

Notice: I included only the necessary files and changes. I skipped the setup process of Laravel, Passport, Socialite and extra checks, try-catch blocks etc. I tried to make the example for begginers too. The example shows the implementation for Facebook auth, but it is the same for other providers like Google.

config/services.php

'facebook' => [
'client_id' => env('FACEBOOK_CLIENT_ID'),
'client_secret' => env('FACEBOOK_CLIENT_SECRET'),
'redirect' => env('FACEBOOK_REDIRECT_URI')
],

.env file

FACEBOOK_CLIENT_ID={the_facebook_client_id}
FACEBOOK_CLIENT_SECRET={the_facebook_client_secret}
FACEBOOK_REDIRECT_URI=

Notice: Apparently the redirect URI is not needed!

Database setup

In the create_users_table migration file

  • we make the user email and password nullables
  • we add provider_name and provider_id.
Schema::create('users', function (Blueprint $table) {
...
$table->string('email')->unique()->nullable();
$table->string('password')->nullable();
...
$table->string('provider_name')->nullable();
$table->string('provider_id')->nullable();
...
});

Route

use App\Http\Controllers\AuthController;...Route::get('social/login', [AuthController::class, 'socialLogin']);

App\Http\Controllers\AuthController.php

/**
* Social Login
*/
public function socialLogin(Request $request)
{
$provider = "facebook"; // or $request->input('provider_name') for multiple providers
$token = $request->input('access_token');
// get the provider's user. (In the provider server)
$providerUser = Socialite::driver($provider)->userFromToken($token);
// check if access token exists etc.. // search for a user in our server with the specified provider id and provider name
$user = User::where('provider_name', $provider)->where('provider_id', $providerUser->id)->first();
// if there is no record with these data, create a new user
if($user == null){
$user = User::create([
'provider_name' => $provider,
'provider_id' => $providerUser->id,
]);
}
// create a token for the user, so they can login
$token = $user->createToken(env('APP_NAME'))->accessToken;
// return the token for usage
return response()->json([
'success' => true,
'token' => $token
]);
}

I hope this helps! Thanks for reading!

John Stavropoulos

Connect with me here:

Check out our software dev agency.

--

--