laravel/socialite
Laravel Socialite provides a fluent OAuth authentication interface for Laravel, with built-in drivers for Bitbucket, Facebook, GitHub, GitLab, Google, LinkedIn, Slack, Twitch, and X. Handles the boilerplate for social login and user retrieval.
## Getting Started
### Minimal Setup
1. **Installation**:
```bash
composer require laravel/socialite
For third-party providers (e.g., GitLab, Slack), install via Socialite Providers:
composer require socialiteproviders/manager
composer require socialiteproviders/<provider-name>
Configuration: Publish the config file:
php artisan vendor:publish --provider="Laravel\Socialite\SocialiteServiceProvider"
Update .env with provider credentials (e.g., GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET).
First Use Case: Redirect users to a provider (e.g., Google) and handle the callback:
use Laravel\Socialite\Facades\Socialite;
// Redirect to Google OAuth
return Socialite::driver('google')->redirect();
// Handle callback
$user = Socialite::driver('google')->user();
Key methods:
redirect(): Initiate OAuth flow.user(): Fetch user data after callback.stateless(): For stateless providers (e.g., Google ID tokens).Authentication Flow:
// Route: GET /auth/google
public function redirectToGoogle()
{
return Socialite::driver('google')->redirect();
}
// Route: GET /auth/google/callback
public function handleGoogleCallback()
{
try {
$user = Socialite::driver('google')->user();
// Create/attach user to your app (e.g., via `$user->email`).
} catch (\Exception $e) {
return redirect('/login')->withError($e->getMessage());
}
}
User Data Handling:
Extract data from the User object:
$user = Socialite::driver('github')->user();
$email = $user->getEmail();
$avatar = $user->getAvatar();
$token = $user->token; // Access token (if needed).
Scopes and Customization:
Configure scopes in config/services.php:
'google' => [
'scopes' => ['profile', 'email', 'openid'], // Custom scopes.
],
Override scopes programmatically:
Socialite::driver('github')->scopes(['user:email', 'read:org']);
Testing with Fakes:
Use the built-in FakeProvider for unit tests:
use Laravel\Socialite\Contracts\Factory;
use Laravel\Socialite\Testing\FakeProvider;
public function testSocialiteLogin()
{
$fakeProvider = FakeProvider::create(['name' => 'Test User']);
$this->app->instance(Factory::class, $fakeProvider);
$user = Socialite::driver('fake')->user();
$this->assertEquals('Test User', $user->getName());
}
Stateless Providers (e.g., Google ID Tokens):
$user = Socialite::driver('google')->stateless()->user();
// No redirect needed; uses ID token for validation.
auth middleware after social login.file, database, redis).scopes(['read:user']) for minimal permissions.Socialite::driver('facebook')->limited().Socialite::driver('twitter')->scopes(['users.read', 'tweet.read']).refreshToken() for providers supporting it (e.g., Google):
$token = Socialite::driver('google')->refreshToken($refreshToken);
State Parameter Mismatch:
state is compared using hash_equals() (built-in since v5.26.1). Avoid manual state handling unless necessary.Missing Scopes:
config/services.php or via scopes():
'github' => [
'scopes' => ['user:email'], // Required for email access.
],
Provider-Specific Bugs:
email scope is missing. Use:
Socialite::driver('facebook')->limited()->scopes(['email']);
'twitter' => [
'oauth_version' => '2.0',
],
openid scope:
Socialite::driver('google')->stateless()->scopes(['openid']);
Token Expiry:
401 Unauthorized.Configuration Errors:
InvalidConfigurationException if client_id or client_secret is missing..env and config/services.php:
GOOGLE_CLIENT_ID=your_id
GOOGLE_CLIENT_SECRET=your_secret
GOOGLE_REDIRECT_URI=http://your-app.test/auth/google/callback
Enable Logging:
Add to config/logging.php to debug OAuth requests:
'channels' => [
'single' => [
'driver' => 'single',
'path' => storage_path('logs/socialite.log'),
'level' => 'debug',
],
],
Log the raw user response:
$user = Socialite::driver('github')->user();
\Log::debug('Socialite User Data:', $user->toArray());
Inspect Redirect URIs:
REDIRECT_URI matches exactly (including http vs https).Socialite::driver('google')->getRedirectUrl() to debug the generated URL.Provider-Specific Tools:
Custom User Mappers:
Extend Laravel\Socialite\Contracts\User to map provider data to your user model:
use Laravel\Socialite\Contracts\User as SocialiteUser;
class CustomUser implements SocialiteUser {
protected $user;
public function __construct($user) {
$this->user = $user;
}
public function getId() {
return $this->user['id'] ?? null;
}
public function getEmail() {
return $this->user['email'] ?? null;
}
// Implement other required methods...
}
Register the mapper in your SocialiteServiceProvider:
public function boot()
{
Socialite::extend('custom', function ($app) {
return new CustomProvider($app['http.client']);
});
}
Custom Providers:
Use SocialiteProviders/Manager to add unsupported providers:
// config/socialite.php
'providers' => [
'custom' => [
'client_id' => env('CUSTOM_CLIENT_ID'),
'client_secret' => env('CUSTOM_CLIENT_SECRET'),
'redirect' => env('CUSTOM_REDIRECT_URI'),
],
],
Create a provider class extending SocialiteProviders\Manager\OAuth2\AbstractProvider.
Decorators:
Decorate the User object to add custom methods:
Socialite::with(['user' => function ($user) {
$user->setCustomAttribute('premium', true);
return $user;
}]);
Testing:
FakeProvider for isolated tests (as shown above).$this->mock(Http::class, function ($mock) {
$mock->shouldReceive('post')
->withArgs(['https://api.github.com/login/oauth/access_token', ...])
->andReturn(['access_token' => 'fake_token']);
});
How can I help you explore Laravel packages today?