How to Implement Custom Facebook OAuth Login in Laravel Without Socialite
In this tutorial, we will learn how to implement OAuth login with Facebook from scratch in a Laravel application, without using any third-party packages like Socialite. We’ll directly interact with Facebook’s OAuth API endpoints to create a custom authentication system. The tutorial will walk through every step, starting from setting up a new Laravel project to configuring the Facebook developer application. We will cover how to handle user authentication, manage access tokens, and store user data in the database. By the end, you'll have a fully functioning Facebook login feature integrated into your Laravel app using a custom API approach, providing a flexible alternative to third-party solutions.
Set up a Facebook Oauth
First, we'll need to create a Facebook App in the Facebook Developer Dashboard. This will provide you with the necessary credentials (App ID and App Secret) to authenticate users.
- Go to the Facebook Developers Account.
- Create a new app and configure the app
- Create credentials for a new OAuth app id and app secret. Set the authorized redirect URI to your Laravel API endpoint.
.env Configuration
Now go to .env file configuration.
FACEBOOK_APP_ID=12xxxxxxxxxxx18978
FACEBOOK_APP_SECRET=82faxxxxxxxxxxxxx7737
FACEBOOK_REDIRECT_URI="${APP_URL}/auth/facebook/callback"
Register in Config
Goto your config/services.php
'facebook' => [
'app_id' => env('FACEBOOK_APP_ID'),
'app_secret' => env('FACEBOOK_APP_SECRET'),
'redirect_uri' => env('FACEBOOK_REDIRECT_URI')
]
Migration Setup
Updating the Migration
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('facebook_id')->nullable();
$table->string('picture_url')->nullable();
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->rememberToken();
$table->timestamps();
});
Updating the User Model Run this command to add tables in database.
protected $fillable = [
'name',
'email',
'facebook_id',
'picture_url'
];
Run this command to add tables in database.
php artisan migrate
Controller Setup
php artisan make:controller FacebookController
We will create multiple functions in a controller which will be our application bussiness logic.
Now goto your FacebookController
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Http;
class FacebookController extends Controller
{
public function redirectToFacebook()
{
$appId = config('services.facebook.app_id');
$redirectUri = config('services.facebook.redirect_uri');
$scope = 'public_profile%20email';
// $display=popup
$url = "https://www.facebook.com/v18.0/dialog/oauth?client_id=$appId&redirect_uri=$redirectUri&scope=$scope";
return redirect()->away($url);
}
public function handleFacebookCallback(Request $request)
{
// // Verify the state parameter to prevent CSRF attacks
// if ($request->input('state') !== session('facebook_state')) {
// // Handle CSRF attack
// return redirect('/login')->with('error', 'CSRF validation failed');
// }
$code = $request->input('code');
$tokenEndpoint = 'https://graph.facebook.com/v18.0/oauth/access_token';
$response = Http::post($tokenEndpoint, [
'client_id' => config('services.facebook.app_id'),
'client_secret' => config('services.facebook.app_secret'),
'redirect_uri' => config('services.facebook.redirect_uri'),
'code' => $code,
]);
$accessTokenResponse = $response->json();
if (isset($accessTokenResponse['access_token'])) {
$tokenType = $accessTokenResponse["token_type"];
$accessToken = $accessTokenResponse["access_token"];
$userData = $this->getUserData($accessToken);
$user = $this->findOrCreateUser($userData);
$userRecord = User::where('email', $user['email'])->where('google_id', $user['google_id'])->first();
if ($userRecord) {
Auth::login($userRecord);
return redirect()->route('home');
} else {
return redirect()->route('login');
}
}
return response()->json(['error' => 'Failed to obtain access token']);
}
private function getUserData($accessToken)
{
$response = Http::get(
'https://graph.facebook.com/v18.0/me',
[
'fields' => 'id,name,first_name,last_name,email,picture',
'access_token' => $accessToken
]
);
return $response->json();
}
private function findOrCreateUser($userData)
{
$user = User::where('email', $userData['email'])->first();
if (!$user) {
$user = User::create([
'facebook_id' => $userData['id'],
'name' => $userData['name'],
'email' => $userData['email'],
'picture_url' => $userData['picture']['data']['url'],
]);
}
return $user;
}
}
Now run this project , open the terminal and run the commands