Socialite Integration
Socialite Integration
Overview
UltraViolet Livewire includes Laravel Socialite integration for social OAuth authentication. This allows users to sign in with their social media accounts using Google, GitHub, Facebook, Twitter, LinkedIn, and Discord.
What's Included
1. Laravel Socialite Package
- laravel/socialite: ^5.12 - Official Laravel OAuth package
- Pre-configured for 6 major OAuth providers
- Secure token handling and user data management
2. Social Login Controller
- SocialiteController - Handles OAuth redirects and callbacks
- Automatic user creation and account linking
- Provider validation and error handling
3. Social Login Buttons Component
- x-social-login-buttons - Reusable Blade component
- Beautiful, branded buttons for each provider
- Hover effects and responsive design
- Customizable provider selection
4. Database Integration
- Social fields added to users table
- Migration for provider data storage
- User model updated with social attributes
Quick Setup
1. Install Dependencies
The Livewire template already includes Laravel Socialite in composer.json:
{
"require": {
"laravel/socialite": "^5.12"
}
}
2. Configure OAuth Providers
Add your OAuth app credentials to .env:
# Google OAuth
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
GOOGLE_REDIRECT_URI=http://localhost:8000/auth/google/callback
# GitHub OAuth
GITHUB_CLIENT_ID=your_github_client_id
GITHUB_CLIENT_SECRET=your_github_client_secret
GITHUB_REDIRECT_URI=http://localhost:8000/auth/github/callback
# Facebook OAuth
FACEBOOK_CLIENT_ID=your_facebook_client_id
FACEBOOK_CLIENT_SECRET=your_facebook_client_secret
FACEBOOK_REDIRECT_URI=http://localhost:8000/auth/facebook/callback
# Twitter OAuth
TWITTER_CLIENT_ID=your_twitter_client_id
TWITTER_CLIENT_SECRET=your_twitter_client_secret
TWITTER_REDIRECT_URI=http://localhost:8000/auth/twitter/callback
# LinkedIn OAuth
LINKEDIN_CLIENT_ID=your_linkedin_client_id
LINKEDIN_CLIENT_SECRET=your_linkedin_client_secret
LINKEDIN_REDIRECT_URI=http://localhost:8000/auth/linkedin/callback
# Discord OAuth
DISCORD_CLIENT_ID=your_discord_client_id
DISCORD_CLIENT_SECRET=your_discord_client_secret
DISCORD_REDIRECT_URI=http://localhost:8000/auth/discord/callback
3. Run Migrations
php artisan migrate
This will add the social fields to your users table.
4. Configure Services
The config/services.php file is already configured with all OAuth providers:
'google' => [
'client_id' => env('GOOGLE_CLIENT_ID'),
'client_secret' => env('GOOGLE_CLIENT_SECRET'),
'redirect' => env('GOOGLE_REDIRECT_URI', env('APP_URL') . '/auth/google/callback'),
],
// ... other providers
Usage
1. Basic Social Login Buttons
Add social login buttons to any auth form:
<x-social-login-buttons :providers="['google', 'github', 'facebook', 'twitter']" />
2. Custom Provider Selection
Choose which providers to display:
<!-- Only Google and GitHub -->
<x-social-login-buttons :providers="['google', 'github']" />
<!-- All providers -->
<x-social-login-buttons :providers="['google', 'github', 'facebook', 'twitter', 'linkedin', 'discord']" />
3. In Login Form
@extends('layouts.guest')
@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">
<!-- Social Login Buttons -->
<x-social-login-buttons :providers="['google', 'github', 'facebook', 'twitter']" />
<!-- Divider -->
<div class="text-center my-3">
<span class="text-muted">or</span>
</div>
<!-- Traditional Login Form -->
<form method="POST" action="{{ route('login') }}">
@csrf
<!-- form fields -->
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
4. In Register Form
@extends('layouts.guest')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Register') }}</div>
<div class="card-body">
<!-- Social Login Buttons -->
<x-social-login-buttons :providers="['google', 'github', 'facebook', 'twitter']" />
<!-- Divider -->
<div class="text-center my-3">
<span class="text-muted">or</span>
</div>
<!-- Traditional Registration Form -->
<form method="POST" action="{{ route('register') }}">
@csrf
<!-- form fields -->
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
OAuth Provider Setup
1. Google OAuth
- Go to Google Cloud Console
- Create a new project or select existing
- Enable Google+ API
- Create OAuth 2.0 credentials
- Add authorized redirect URIs:
http://localhost:8000/auth/google/callback(development)https://yourdomain.com/auth/google/callback(production)
2. GitHub OAuth
- Go to GitHub Developer Settings
- Click "New OAuth App"
- Fill in application details:
- Application name: Your app name
- Homepage URL:
http://localhost:8000 - Authorization callback URL:
http://localhost:8000/auth/github/callback
3. Facebook OAuth
- Go to Facebook Developers
- Create a new app
- Add Facebook Login product
- Configure OAuth redirect URIs:
http://localhost:8000/auth/facebook/callback
4. Twitter OAuth
- Go to Twitter Developer Portal
- Create a new app
- Enable OAuth 2.0
- Set callback URL:
http://localhost:8000/auth/twitter/callback
5. LinkedIn OAuth
- Go to LinkedIn Developers
- Create a new app
- Add Sign In with LinkedIn product
- Set redirect URL:
http://localhost:8000/auth/linkedin/callback
6. Discord OAuth
- Go to Discord Developer Portal
- Create a new application
- Go to OAuth2 settings
- Add redirect URI:
http://localhost:8000/auth/discord/callback
How It Works
1. User Clicks Social Button
<a href="route-auth.social.redirect-google.html">
Sign in with Google
</a>
2. Redirect to Provider
The SocialiteController::redirect() method:
- Validates the provider
- Redirects to the OAuth provider's authorization page
3. User Authorizes App
User logs in to their social account and authorizes your app.
4. Callback Handling
The SocialiteController::callback() method:
- Receives the authorization code
- Exchanges it for an access token
- Fetches user data from the provider
- Creates or updates the user account
- Logs the user in
5. User Data Storage
Social user data is stored in the users table:
provider- OAuth provider name (google, github, etc.)provider_id- User's ID from the provideravatar- User's profile picture URL
Customization
1. Custom Button Styling
Override the component styles:
<style>
.social-login-btn {
/* Your custom styles */
border-radius: 8px;
font-weight: 600;
}
.social-login-google:hover {
background-color: #your-color;
}
</style>
2. Custom Provider Icons
Replace the SVG icons in the component:
@if ($provider === 'google')
<img src="{{ asset('images/icons/google.svg') }}" alt="Google" width="18" height="18">
<span>Google</span>
@endif
3. Additional User Data
Extend the user creation to store more social data:
// In SocialiteController::createUserFromSocial()
return User::create([
'name' => $socialUser->getName() ?: $socialUser->getNickname(),
'email' => $socialUser->getEmail(),
'email_verified_at' => now(),
'password' => Hash::make(Str::random(24)),
'provider' => $provider,
'provider_id' => $socialUser->getId(),
'avatar' => $socialUser->getAvatar(),
'social_data' => json_encode($socialUser->getRaw()), // Store additional data
]);
Security Considerations
1. Provider Validation
The controller validates allowed providers:
private function validateProvider($provider)
{
$allowedProviders = ['google', 'github', 'facebook', 'twitter', 'linkedin', 'discord'];
if (!in_array($provider, $allowedProviders)) {
abort(404, 'Provider not supported');
}
}
2. Error Handling
Graceful error handling for OAuth failures:
try {
$socialUser = Socialite::driver($provider)->user();
} catch (\Exception $e) {
return redirect()
->route('login')
->with('error', 'Unable to login with ' . ucfirst($provider) . '. Please try again.');
}
3. Account Linking
Existing users can link social accounts:
if ($user) {
// Update existing user with social provider info
$this->updateUserSocialInfo($user, $socialUser, $provider);
} else {
// Create new user
$user = $this->createUserFromSocial($socialUser, $provider);
}
Testing
1. Test Social Login
use Laravel\Socialite\Facades\Socialite;
test('can login with google', function () {
$user = User::factory()->create([
'provider' => 'google',
'provider_id' => '123456789',
]);
$response = $this->get('/auth/google');
$response->assertRedirect();
});
2. Test Social Callback
test('handles google callback', function () {
$mockUser = Mockery::mock('Laravel\Socialite\Two\User');
$mockUser->shouldReceive('getId')->andReturn('123456789');
$mockUser->shouldReceive('getName')->andReturn('John Doe');
$mockUser->shouldReceive('getEmail')->andReturn('john@example.com');
$mockUser->shouldReceive('getAvatar')->andReturn('https://example.com/avatar.jpg');
Socialite::shouldReceive('driver->user')->andReturn($mockUser);
$response = $this->get('/auth/google/callback');
$response->assertRedirect('/dashboard');
$this->assertDatabaseHas('users', [
'provider' => 'google',
'provider_id' => '123456789',
]);
});
Troubleshooting
1. OAuth Redirect Mismatch
Error: "redirect_uri_mismatch"
Solution: Ensure the redirect URI in your OAuth app matches exactly:
- Development:
http://localhost:8000/auth/{provider}/callback - Production:
https://yourdomain.com/auth/{provider}/callback
2. Invalid Client
Error: "invalid_client"
Solution: Check your client ID and secret in .env:
GOOGLE_CLIENT_ID=your_actual_client_id
GOOGLE_CLIENT_SECRET=your_actual_client_secret
3. Scope Issues
Error: Missing user data
Solution: Some providers require specific scopes. Check the provider's documentation for required scopes.
4. HTTPS Required
Error: OAuth fails in production
Solution: Most OAuth providers require HTTPS in production. Ensure your production site uses SSL.
Production Deployment
1. Update Redirect URIs
Update all OAuth app settings with production URLs:
https://yourdomain.com/auth/google/callbackhttps://yourdomain.com/auth/github/callback- etc.
2. Environment Variables
Set production OAuth credentials:
APP_URL=https://yourdomain.com
GOOGLE_CLIENT_ID=production_client_id
GOOGLE_CLIENT_SECRET=production_client_secret
# ... other providers
3. Security Headers
Add security headers for OAuth:
// In your middleware
return $next($request)->withHeaders([
'X-Frame-Options' => 'DENY',
'X-Content-Type-Options' => 'nosniff',
]);
Resources
- Laravel Socialite: laravel.com/docs/socialite
- Google OAuth: developers.google.com/identity
- GitHub OAuth: docs.github.com/en/developers
- Facebook OAuth: developers.facebook.com/docs/facebook-login
Summary
Key Features:
- ✅ 6 OAuth providers supported
- ✅ Beautiful, branded login buttons
- ✅ Automatic user creation and linking
- ✅ Secure token handling
- ✅ Error handling and validation
- ✅ Customizable and extensible
- ✅ Production-ready configuration
The socialite integration makes user authentication seamless and modern! 🚀