Why Use LinkedIn Social Login in Laravel?
Social authentication simplifies registration and login, boosting user conversion. Laravel Socialite handles OAuth providers like LinkedIn effortlessly, supporting secure sign-in without managing passwords.
Table Of Content
1 Prerequisites
- PHP ≥ 8.2
- Composer
- MySQL (or compatible database)
- Active LinkedIn account
2 Introduction
In this comprehensive guide, you'll learn how to add social authentication (social login) to your Laravel 11 application using the powerful Laravel Socialite package combined with Laravel Breeze for modern authentication scaffolding.
Laravel Socialite is an official, lightweight package that simplifies OAuth-based authentication with various providers. It handles the complex parts of the OAuth flow — such as redirects, token exchanges, and user data retrieval — so you can focus on building your application.
Officially supported providers in Laravel Socialite (as of Laravel 11/12):
- X (formerly Twitter)
- LinkedIn (using OpenID Connect — config key: linkedin-openid)
- GitHub
- GitLab
- Bitbucket
- Slack
For hundreds of additional providers (Discord, Reddit, Spotify, PayPal, and more), check out the community-maintained Socialite Providers package, which extends Socialite seamlessly.
In this tutorial, we'll focus on implementing LinkedIn sign-in using Socialite + Breeze in Laravel 11 — a popular choice for professional networking apps. By the end, users will be able to register or log in with their LinkedIn account in just a few clicks, improving UX and conversion rates. Ready to get started? Let's dive into the setup.
3 Create a Fresh Laravel 11 Project
3.1 Install Laravel Project
Use the following command to install new Laravel Project.
composer create-project laravel/laravel linkedin-auth-app
Then, navigate to your project directory:
cd linkedin-auth-app
3.2 Set Up Database Configuration
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=linkedin_auth
DB_USERNAME=root
DB_PASSWORD=
4 Install Laravel Breeze & Socialite
4.1 Install Breeze Package
composer require laravel/breeze --dev
After Composer has installed the Laravel Breeze package, you should run the breeze:install Artisan command. This command publishes the authentication views, routes, controllers, and other resources to your application.
php artisan breeze:install
php artisan migrate
npm install
npm run dev
4.2 Install Socialite Package
composer require laravel/socialite
5 Create a LinkedIn Developer Application
5.1 Login into LinkedIn Developer App
5.2 Create App


5.3 App Dashboard


6 Configure Credentials in Laravel
6.1 Add the LinkedIn API Credentials in .env
LINKEDIN_CLIENT_ID=Your Client ID
LINKEDIN_CLIENT_SECRET=Your Client Secret
LINKEDIN_REDIRECT_URI=http://127.0.0.1:8000/callback/linkedin
6.2 Add the LinkedIn API .env key in config/services.php
<?php
return [
// Other services ..
'linkedin' => [
'client_id' => env('LINKEDIN_CLIENT_ID'),
'client_secret' => env('LINKEDIN_CLIENT_SECRET'),
'redirect' => env('LINKEDIN_REDIRECT_URI'),
],
];
?>
6.3 Add linkedin_id Column to Users Table
php artisan make:migration add_linkedin_id_to_users
In the generated new migration file, update the up and down methods as described below:
database/migrations/2024_05_24_120820_add_linkedin_id_to_users.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->string('linkedin_id')->after('password')->nullable()->unique();
});
}
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('linkedin_id');
});
}
};
Use the following command to run the migration to update your database.
php artisan migrate
6.4 Update the User Model
app/Models/User.php
<?php
namespace App\Models;
// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name',
'email',
'password',
'linkedin_id'
];
/**
* The attributes that should be hidden for serialization.
*
* @var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* Get the attributes that should be cast.
*
* @return array
*/
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
}
?>
7 Create Socialite Controller
php artisan make:controller Socialite/LinkedinController
app/Http/Controllers/Socialite/LinkedinController.php
<?php
namespace App\Http\Controllers\Socialite;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Laravel\Socialite\Facades\Socialite;
use App\Models\User;
use Exception;
class LinkedinController extends Controller
{
public function redirect()
{
return Socialite::driver('linkedin')->redirect();
}
public function callback()
{
try {
$linkedinUser = Socialite::driver('linkedin')->user();
$user = User::where('linkedin_id', $linkedinUser->id)->first();
if ($user) {
Auth::login($user);
return redirect('/dashboard');
}
// Optional: Check if email exists to avoid duplicates
$existingUser = User::where('email', $linkedinUser->email)->first();
if ($existingUser) {
// Handle conflict (e.g., link accounts or show error)
return redirect('/login')->with('error', 'Email already registered.');
}
$newUser = User::create([
'name' => $linkedinUser->name,
'email' => $linkedinUser->email,
'linkedin_id' => $linkedinUser->id,
'password' => bcrypt(str_random(16)), // Random secure password
]);
Auth::login($newUser);
return redirect('/dashboard');
} catch (Exception $e) {
return redirect('/login')->with('error', 'LinkedIn login failed: ' . $e->getMessage());
}
}
}
?>
8 Define Routes (routes/web.php)
use App\Http\Controllers\Socialite\LinkedinController;
Route::get('/auth/linkedin', [LinkedinController::class, 'redirect'])->name('auth.linkedin');
Route::get('/auth/callback/linkedin', [LinkedinController::class, 'callback']);
9 Add LinkedIn Login Button to View
resources/views/auth/login.blade.php(Breeze), add:
<a href="{{ route('auth.linkedin') }}" class="btn btn-primary">
Sign in with LinkedIn
</a>
Style with CSS or use an official LinkedIn button image (with proper alt text: "Sign in with LinkedIn").
10 Folder Structure
11 Run and Test the Application
php artisan serve
Visit http://127.0.0.1:8000/login and test the LinkedIn button.
Best Practices & Troubleshooting
PHP Developer & Technical Writer · 10+ years building web applications with CodeIgniter and Laravel
Revathi specializes in PHP backend development, authentication systems, and REST API design.
She writes practical, production-tested tutorials at Get Sample Code to help developers
build secure applications faster.
You need PHP 8.2 or higher, Composer, a MySQL database, and a LinkedIn account to create a developer app.
Run `composer create-project laravel/laravel linkedin-auth-app`, then `cd linkedin-auth-app`.
Install Breeze with `composer require laravel/breeze --dev`, then `php artisan breeze:install`, `php artisan migrate`, `npm install`, and `npm run dev`. Install Socialite with `composer require laravel/socialite`.
Go to the LinkedIn Developer Portal[](https://developer.linkedin.com/), create an app, fill in details, and set the authorized redirect URL to `http://127.0.0.1:8000/callback/linkedin`.
Add `LINKEDIN_CLIENT_ID`, `LINKEDIN_CLIENT_SECRET`, and `LINKEDIN_REDIRECT_URI=http://127.0.0.1:8000/callback/linkedin` to the `.env` file. Then add the 'linkedin' array to `config/services.php`.
Run `php artisan make:migration add_linkedin_id_to_users`, add `$table->string('linkedin_id')->nullable()->unique();` in the migration, then run `php artisan migrate`. Update the User model's `$fillable` array to include 'linkedin_id'.
Run `php artisan make:controller LinkedinSocialiteController`, then implement `redirectToLinkedin()` to redirect using Socialite and `handleCallback()` to handle the user response, find or create the user, and log them in.
In `routes/web.php`, add `Route::get('auth/linkedin', [LinkedinSocialiteController::class, 'redirectToLinkedin']);` and `Route::get('callback/linkedin', [LinkedinSocialiteController::class, 'handleCallback']);`.
In the login view (e.g., from Breeze), add `<a href='{{ url('auth/linkedin') }}'><img src='images/linkedin_button.png'></a>` or a similar button linking to `/auth/linkedin`.
The redirect URL in the LinkedIn app settings must exactly match the `LINKEDIN_REDIRECT_URI` in `.env` and the callback route (e.g., `http://127.0.0.1:8000/callback/linkedin`).
Ensure you ran `composer require laravel/socialite` and `composer dump-autoload`.
Check for exceptions in `handleCallback()` (use `dd($e->getMessage())`). Common issues: invalid credentials, scope problems, or network errors.
The tutorial checks by `linkedin_id`. For email matching, modify the query to `where('email', $user->email)` or combine both.
Run `php artisan serve`, visit `http://127.0.0.1:8000`, go to login, click the LinkedIn button, and complete the OAuth flow.
12 Conclusion
Written by Revathi M
Frequently Asked Questions
