Choosing to log in through social login provides many benefits to users. Laravel has a famous package called “Socialite,” which you can use to create an authentication system through social media accounts.
But why should you use the Socialite package?
Socialite simplifies the setup of OAuth authentication with various providers, including LinkedIn.
It handles most of the boilerplate code needed for OAuth, such as redirecting to the authentication page, handling callbacks, and obtaining user information. This reduces the amount of code developers need to write and debug.
Follow this step-by-step guide to integrate LinkedIn Login into the Laravel 11 application through the Socialite package.
Step 1: Install the Laravel Project
composer create-project --prefer-dist laravel/laravel laravellinkedinlogin
Go inside the “laravellinkedin” project.
cd laravellinkedin
Step 2: Install Bootstrap Authentication
Install the laravel/ui package to use the authentication system with Bootstrap 5 css framework.
composer require laravel/ui
Our next step is to create auth scaffolding using this command:
php artisan ui bootstrap --auth
Also, install the bootstrap-icons package using this command:
npm install bootstrap-icons --save-dev
Now install the remaining dependencies using this command:
npm install
Import the bootstrap-icons.min.css file inside the resources/js/app.js like this:
import './bootstrap'; import 'bootstrap-icons/font/bootstrap-icons.css';
Start the Vite development server using this command:
npm run dev
Step 3: Set up a MySQL database
Instantly configure the database in the .env file.
//.env DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=8889 DB_DATABASE=laravellinkedin DB_USERNAME=root DB_PASSWORD=root
Inside the database/migrations folder, you will see the create_users_table.php file.
We need to add two more fields in that file:
- oauth_id: A unique ID is generated when logged in.
- oauth_type: It will be linkedin since we are using linkedin to signin.
public function up(): void { Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('oauth_id')->nullable(); $table->string('oauth_type')->nullable(); $table->string('password'); $table->rememberToken(); $table->timestamps(); });
Immediately migrate the table using the following command.
php artisan migrate
Step 4: Install the laravel/socialite package
The Socialite package makes building authentication with popular social networks simple. So, we are using this Laravel-specific package.
composer require laravel/socialite
Register the SocialiteServiceProvider inside the bootstrap/providers.php file.
<?php return [ App\Providers\AppServiceProvider::class, Laravel\Socialite\SocialiteServiceProvider::class, ];
Step 5: Create a LinkedIn developer application
Go to LinkedIn’s developers portal by following the URL: https://www.linkedin.com/developer/apps
Login via your Linkedin account. You will see something like this.
You need to click the “Create app” button, as shown in the figure above.
You will see something like this:
After creating an application, your dashboard looks like this:
If you move to the “Auth” tab, you will see Client ID, Client Secret, and Authorized redirect URLs for your app like this:
So, we have three things here to copy:
- client_id
- client_secret
- Redirect URL: http://localhost:8000/auth/linkedin/callback
Now, copy all three fields and add them to the .env file like this:
CLIENT_ID=xxxx [Your id] CLIENT_SECRET=xxxx [Your secret] REDIRECT=http://localhost:8000/auth/linkedin/callback
Open config >> services.php file and add the configuration array like this:
'linkedin-openid' => [ 'client_id' => env('CLIENT_ID'), 'client_secret' => env('CLIENT_SECRET'), 'redirect' => env('REDIRECT'), ],
Go to the Linkedin developer application and switch to the “Products” tab:
Here, you need to give access to two products:
- Sign In with LinkedIn using OpenID Connect
- Share on LinkedIn
After getting the access, the “Products” tab looks like this:
Ensure you have a valid client ID, client secret, and enough permission to access the linkedin login api.
Step 6: Generate a controller
Create a controller called LinkedinController that handles the LinkedIn authentication routes.
php artisan make:controller LinkedinController
Add the below code inside the LinkedinController.php file:
<?php namespace App\Http\Controllers; use Auth; use Exception; use Laravel\Socialite\Facades\Socialite; use App\Models\User; use Illuminate\Http\Request; class LinkedinController extends Controller { public function linkedinRedirect() { return Socialite::driver('linkedin-openid')->redirect(); } public function linkedinCallback(Request $request) { try { // First, check if we received the code parameter. if (!$request->has('code')) { throw new Exception('Authorization request returned without a code parameter.'); } // Get the user from LinkedIn using the code. $user = Socialite::driver('linkedin-openid')->stateless()->user(); $linkedinUser = User::where('oauth_id', $user->id)->first(); if ($linkedinUser) { Auth::login($linkedinUser); return redirect('/home'); } else { $user = User::create([ 'name' => $user->name, 'email' => $user->email, 'password' => md5(rand(1, 10000)), 'oauth_id' => $user->id, 'oauth_type' => 'linkedin', ]); Auth::login($user); return redirect('/home'); } } catch (Exception $e) { // Optionally, handle or log the error more appropriately. dd($e->getMessage()); } } }
In this LinkedinController.php file, we added two functions:
- linkedinRedirect(): It will redirect to the linkedin application and try to login through the linkedin.
- linkedinCallback(): After a successful login, it will redirect you to our laravel application’s home route.
We also need to modify the App/Models/User.php file like this:
<?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<int, string> */ protected $fillable = [ 'name', 'email', 'password', 'oauth_id', 'oauth_type' ]; /** * The attributes that should be hidden for serialization. * * @var array<int, string> */ protected $hidden = [ 'password', 'remember_token', 'two_factor_recovery_codes', 'two_factor_secret', ]; /** * Get the attributes that should be cast. * * @return array<string, string> */ protected function casts(): array { return [ 'email_verified_at' => 'datetime', 'password' => 'hashed', ]; } /** * The accessors to append to the model's array form. * * @var array */ protected $appends = [ 'profile_photo_url', ]; }
Step 7: Define the routes
Register the routes for two LinkedinController functions like this in the routes/web.php file:
<?php use Illuminate\Support\Facades\Route; use App\Http\Controllers\LinkedinController; Route::get('/', function () { return view('welcome'); }); Auth::routes(); Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home'); Route::get('auth/linkedin', [LinkedinController::class, 'linkedinRedirect']); Route::get('auth/linkedin/callback', [LinkedinController::class, 'linkedinCallback']);
Step 8: Modify the login.blade.php file
Finally, we need to add a button to the login page so users can log in through the LinkedIn page.
Let’s open the resources/views/auth/login.blade.php file and replace it with the code below.
@extends('layouts.app') @section('content') <div class="container"> <div class="row justify-content-center"> <div class="col-md-8"> <div class="card"> <div class="card-header">{{ __('Login') }}</div> <div class="card-body"> <form method="POST" action="{{ route('login') }}"> @csrf <div class="mb-3 row"> <label for="email" class="col-md-4 col-form-label text-md-end">{{ __('Email Address') }}</label> <div class="col-md-6"> <input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus> @error('email') <span class="invalid-feedback" role="alert"> <strong>{{ $message }}</strong> </span> @enderror </div> </div> <div class="mb-3 row"> <label for="password" class="col-md-4 col-form-label text-md-end">{{ __('Password') }}</label> <div class="col-md-6"> <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password"> @error('password') <span class="invalid-feedback" role="alert"> <strong>{{ $message }}</strong> </span> @enderror </div> </div> <!-- LinkedIn Login Button --> <div class="mb-3 row"> <div class="col-md-8 offset-md-4"> <a href="{{ url('auth/linkedin') }}" class="btn btn-linkedin btn-lg btn-block" style="background-color: #0E62BC; color: #ffffff;"> <i class="bi bi-linkedin me-2"></i> Login with LinkedIn </a> </div> </div> <div class="mb-3 row"> <div class="col-md-6 offset-md-4"> <div class="form-check"> <input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}> <label class="form-check-label" for="remember"> {{ __('Remember Me') }} </label> </div> </div> </div> <div class="mb-0 row"> <div class="col-md-8 offset-md-4"> <button type="submit" class="btn btn-primary"> {{ __('Login') }} </button> @if (Route::has('password.request')) <a class="btn btn-link" href="{{ route('password.request') }}"> {{ __('Forgot Your Password?') }} </a> @endif </div> </div> </form> </div> </div> </div> </div> </div> @endsection
We used Bootstrap 5 for styling and bootstrap-icons to make it more elegant and attractive.
Save the file, go to the terminal, and start the Laravel development server using this command:
php artisan serve
Go to the browser and navigate to this URL: http://localhost:8000/login
If you click on the “Login with LinkedIn” button, you will be redirected like this:
When you are successful, you will be redirected to your Laravel application as a logged-in user like this:
If you check the users table in the mysql database, it looks like this:
That’s it! We successfully logged in through Linkedin.
Here is the complete Github Code.
Shakeel
I did exactly what you have written but an error popped up when I click log in with LinkedIn.
ErrorException
Trying to access array offset on the value of type null
In socialliteManager when the function is trying to access LinkedIn API key/secret key from Services.php it is returning null because it can’t find anything related to Linkedin. don’t know what the problem is.
do I have to run any command after adding this to services.php???
‘linkedin’ => [
‘client_id’ => env(‘LINKEDIN_CLIENT_ID’),
‘client_secret’ => env(‘LINKEDIN_CLIENT_SECRET’),
‘redirect’ => ‘http://localhost:8000/callback’,
],
Nandhini
clear cache.. then it will works fine
thanks
pintu yadav
My linkedin not working proper