Documentation

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

  1. Go to Google Cloud Console
  2. Create a new project or select existing
  3. Enable Google+ API
  4. Create OAuth 2.0 credentials
  5. Add authorized redirect URIs:
    • http://localhost:8000/auth/google/callback (development)
    • https://yourdomain.com/auth/google/callback (production)

2. GitHub OAuth

  1. Go to GitHub Developer Settings
  2. Click "New OAuth App"
  3. 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

  1. Go to Facebook Developers
  2. Create a new app
  3. Add Facebook Login product
  4. Configure OAuth redirect URIs:
    • http://localhost:8000/auth/facebook/callback

4. Twitter OAuth

  1. Go to Twitter Developer Portal
  2. Create a new app
  3. Enable OAuth 2.0
  4. Set callback URL: http://localhost:8000/auth/twitter/callback

5. LinkedIn OAuth

  1. Go to LinkedIn Developers
  2. Create a new app
  3. Add Sign In with LinkedIn product
  4. Set redirect URL: http://localhost:8000/auth/linkedin/callback

6. Discord OAuth

  1. Go to Discord Developer Portal
  2. Create a new application
  3. Go to OAuth2 settings
  4. 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 provider
  • avatar - 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/callback
  • https://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

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! 🚀