Allowing users to use their Twitter / X account to log into your Laravel application adds a lot of convenience for your users.
In this step-by-step guide, I’ll show you how to quickly add a ‘Login With Twitter’ option to your Laravel application using the Laravel Socialite package.
To speed up the process of building this feature, I’ll be using Laravel Jetstream to generate authentication scaffolding for us. If you have an existing application or prefer a different setup, you can easily adapt these steps as well.
Step 1: Install Laravel
If you haven’t already, create a new Laravel project using Composer:
composer create-project --prefer-dist laravel/laravel twitter-login-app
Navigate to your project directory:
cd twitter-login-app
Step 2: Install Jetstream
Now, let’s install Laravel Jetstream to take advantage of its scaffolding for adding the Twitter login feature. After completing this step you’ll have a working login form and a dashboard which is only accessible when logged in.
Execute the following artisan command:
composer require laravel/jetstream
Publish Jetstream’s assets and run its installation:
php artisan jetstream:install livewire
Follow the prompts to configure Jetstream according to your preferences.
Step 3: Install Socialite
Next, we’ll install the Laravel Socialite package using Composer and migrate the database tables it needs by running:
composer require laravel/socialite
php artisan migrate
Step 4: Starting the Local Application
Note that we won’t be running php artisan serve
this time to launch our local site, as it uses http://localhost:8000 and Twitter Developer Portal requires us to create apps on an HTTPS-secured domain.
To ensure that your Laravel site can be accessed over HTTPS, you have two options:
- Run your site on a local domain, with HTTPS, on a test domain like for example:
https://your-site.test
You can achieve this using tools such as:
- Laravel Herd (use:
herd secure
) - Laravel Valet (use:
valet secure
) - Laravel Sail (use:
sail share
)
- Running Your Site on a Local Domain with HTTPS via ngrok:
Ngrok is a third-party tool that allows HTTPS access to your local site. To use it, install ngrok from their site (it has a free version), and then run the following commands:
php artisan serve
ngrok http 8000
Your terminal will display an HTTPS URL, which you can use in your .env
file and on the Twitter Developer Portal later. Please note that if you use this method, the Jetstream CSS and JS may appear distorted. You can fix this by making changes to app/Http/Middleware/TrustProxies.php
as follows:
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Middleware\TrustProxies as Middleware;
use Illuminate\Http\Request;
class TrustProxies extends Middleware
{
protected $proxies = '*'; // changed from default ''
// keep the rest unchanged ...
}
Regardless of the option you choose, please test it by opening your site and clicking the login link. If the form displays correctly, proceed to step 5.
Step 5: Create Twitter App Credentials
To create our Twitter app and receive the app credentials open the Twitter Developer Portal and sign up or log in.
There you can follow these steps to create your app:
- On the dashboard page Click “Add App”
- Fill in a App name
- Copy the API Key and Secret and keep them for later use
- Click “Set up” on the “App details” page
- Fill in the form and make sure to:
- Check “Read”
- Check “Request email from users”
- As “Type of App” check “Web App, Automated App or Bot”
- Fill in “Callback URI / Redirect URI” with: https://your-site.test/auth/twitter/callback
- Fill in “Website URL with: https://your-site.test
- Fill in a terms of service link, unless it’s for production use it can be any URL, even non-existent, like: https://your-site.test/terms-of-service
- Fill in a privacy policy link, unless it’s for production use it can be any URL, even non-existent, like: https://your-site.test/privacy-policy
- Save your settings
To guide you through the steps listed above, I’ve included screenshots of the entire process below:
Make sure you have the API Key and Secret, and move on to the next step.
Step 6: Add Twitter App Credentials to the Config
In your Laravel application, open the config/services.php
file. Add the Twitter credentials you obtained in the previous step:
'twitter' => [
'client_id' => env('TWITTER_CLIENT_API_KEY'),
'client_secret' => env('TWITTER_CLIENT_API_SECRET_KEY'),
'redirect' => env('TWITTER_CALLBACK_URL'),
],
Make sure to set these values in your .env
file:
TWITTER_CLIENT_API_KEY=YOUR_CLIENT_ID
TWITTER_CLIENT_API_SECRET_KEY=YOUR_CLIENT_SECRET
TWITTER_CALLBACK_URL=https://your-domain.test/auth/twitter/callback
Step 7: Add Database Column to Store twitter_id
Extend your user database by creating a migration to add a twitter_id
column:
php artisan make:migration add_twitter_id_to_users
In the generated migration file, modify the up
and down
methods as follows:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
Schema::table('users', function (Blueprint $table) {
$table->string('twitter_id')->after('remember_token')->nullable()->unique();
});
});
}
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('twitter_id');
});
}
};
Run the following artisan command to add our new column:
php artisan migrate
Step 8: Modify the User Model
In your User model (typically located at app/Models/User.php
), make the twitter_id
column fillable for mass assignment by adding it to the $fillable
array.
<?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;
use Laravel\Fortify\TwoFactorAuthenticatable;
use Laravel\Jetstream\HasProfilePhoto;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens;
use HasFactory;
use HasProfilePhoto;
use Notifiable;
use TwoFactorAuthenticatable;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
'twitter_id', // Add 'twitter_id' to the fillable array.
];
/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
'two_factor_recovery_codes',
'two_factor_secret',
];
/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
/**
* The accessors to append to the model's array form.
*
* @var array<int, string>
*/
protected $appends = [
'profile_photo_url',
];
}
Step 9: Create TwitterController
Add a controller named TwitterController
to your application by running the Artisan command:
php artisan make:controller TwitterController
In TwitterController.php
, add the methods redirectToTwitter
and handleTwitterCallback
which will handle Twitter login and callback.
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
use Laravel\Socialite\Facades\Socialite;
use Throwable;
class TwitterController extends Controller
{
/**
* Redirect to Twitter
*
* @return RedirectResponse
*/
public function redirectToTwitter(): RedirectResponse
{
return Socialite::driver('twitter')->redirect();
}
/**
* Handle Twitter authentication callback
*
* @return RedirectResponse
*/
public function handleTwitterCallback(): RedirectResponse
{
try
{
$user = Socialite::driver('twitter')->user();
}
catch (Throwable $e) {
return redirect(route('login'))->with('error', 'Twitter authentication failed.');
}
$existingUser = User::where('twitter_id', $user->id)->first();
if ($existingUser){
Auth::login($existingUser);
} else {
$newUser = User::updateOrCreate([
'email' => $user->email
], [
'name' => $user->name,
'twitter_id'=> $user->id,
'password' => bcrypt(request(Str::random())) // Set a random password
]);
Auth::login($newUser);
}
return redirect()->intended('dashboard');
}
}
Step 10: Add Routes
Add routes for Twitter login and callback URL’s to your routes/web.php
file, like shown below:
<?php
use App\Http\Controllers\TwitterController;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "web" middleware group. Make something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Route::middleware(['auth:sanctum', 'verified'])->get('/dashboard', function () {
return view('dashboard');
})->name('dashboard');
Route::controller(TwitterController::class)->group(function(){
Route::get('auth/twitter', 'redirectToTwitter')->name('auth.twitter');
Route::get('auth/twitter/callback', 'handleTwitterCallback');
});
Step 11: Update Login Blade File
In this step we will update the login page UI to include a Twitter login button.
Edit the resources/views/auth/login.blade.php
to add a button to sign in with Twitter, as shown in the code sample below:
<x-guest-layout>
<x-authentication-card>
<x-slot name="logo">
<x-authentication-card-logo />
</x-slot>
<x-validation-errors class="mb-4" />
@if (session('status'))
<div class="mb-4 font-medium text-sm text-green-600">
{{ session('status') }}
</div>
@endif
<form method="POST" action="{{ route('login') }}">
@csrf
<div>
<x-label for="email" value="{{ __('Email') }}" />
<x-input id="email" class="block mt-1 w-full" type="email" name="email" :value="old('email')" required autofocus autocomplete="username" />
</div>
<div class="mt-4">
<x-label for="password" value="{{ __('Password') }}" />
<x-input id="password" class="block mt-1 w-full" type="password" name="password" required autocomplete="current-password" />
</div>
<div class="block mt-4">
<label for="remember_me" class="flex items-center">
<x-checkbox id="remember_me" name="remember" />
<span class="ml-2 text-sm text-gray-600">{{ __('Remember me') }}</span>
</label>
</div>
{{-- Begin custom changes in login.blade.php --}}
<div class="flex mt-4 justify-between">
<a href="{{ route('auth.twitter') }}" style="background-color: #183153" class="inline-flex items-center px-2 float-left py-2 bg-gray-800 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-gray-700 focus:bg-gray-700 active:bg-gray-900 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 transition ease-in-out duration-150 h-10 px-2 py-2 mt-2 font-semibold text-xs text-white float-left transition-colors duration-150 rounded-lg uppercase focus:shadow-outline0 bg-gray-800 hover:bg-gray-700 focus:bg-gray-700 active:bg-gray-900">
<img src="https://www.cdnlogo.com/logos/t/96/twitter-icon.svg" class="w-4 p-1 mr-2">
Login with Twitter
</a>
<x-button class="h-10 px-2 py-2 m-2 ml-6 font-semibold text-xs text-white float-right transition-colors duration-150 rounded-lg uppercase focus:shadow-outline0 bg-gray-800 hover:bg-gray-700 focus:bg-gray-700 active:bg-gray-900">
{{ __('Log in') }}
</x-button>
</div>
<div class="block mt-4 text-right">
@if (Route::has('password.request'))
<a class="underline text-sm text-gray-600 hover:text-gray-900 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" href="{{ route('password.request') }}">
{{ __('Forgot your password?') }}
</a>
@endif
</div>
{{-- End custom changes in login.blade.php --}}
</form>
</x-authentication-card>
</x-guest-layout>
Step 12: Testing Logging in With Twitter/X
- Go to
https://your-localsite.test/login
to access the login form (or use ngrok url) - On the login page, click the newly added “Login with Twitter” button.
- You are being directed to the Twitter permission window
- Here, you can log into your Twitter account
- After you’ve authorized the application, your TwitterLoginController will receive a callback with the user data.
- The controller creates or updates a user and adds the Twitter ID to it if not present already.
- Finally, you’ll be automatically redirected to the intended dashboard.
To guide you through the testing I’ve included screenshots of the entire process below:
Conclusion
Congratulations! You’ve successfully added the option for users to log into your app using their existing Twitter/X account. This makes your Laravel application more accessible and user-friendly.
If you have any questions or need further assistance, feel free to explore the provided references for more details on Laravel Jetstream and Laravel Socialite. Happy coding!
References
This entry is part 3 of 4 in the series Authenticating With Laravel Socialite
- Adding Login With Google to Your Laravel App Using Socialite
- Login to Your Laravel App With Facebook Using Socialite
- Login to Your Laravel App With Twitter / X Using Socialite
- Login to Your Laravel App With GitHub Using Socialite