Social Login in Laravel with Socialite

4 min readUpdated on

Socialite performs OAuth redirects and returns provider identity; your application owns account linking, session security and recovery. Configure environment-specific callback URLs and use the current provider documentation for console clicks, which change more often than code.

php
<?php

declare(strict_types=1);

return [
    'google' => ['client_id' => env('GOOGLE_CLIENT_ID'), 'client_secret' => env('GOOGLE_CLIENT_SECRET'), 'redirect' => env('GOOGLE_REDIRECT_URI')],
    'facebook' => ['client_id' => env('FACEBOOK_CLIENT_ID'), 'client_secret' => env('FACEBOOK_CLIENT_SECRET'), 'redirect' => env('FACEBOOK_REDIRECT_URI'), 'graph_version' => env('FACEBOOK_GRAPH_VERSION', 'v24.0')],
];

At callback, match the immutable provider ID first. An email can be absent, changed or already owned by a password account, so account linking needs an authenticated confirmation path. If your schema requires a password for a social-only user, generate it rather than using a predictable placeholder.

php
<?php

declare(strict_types=1);

use Illuminate\Support\Str;

$user = User::query()->firstOrCreate(
    ['email' => $providerUser->getEmail()],
    ['name' => $providerUser->getName() ?? 'New user', 'password' => Str::password(40)],
);

Store provider tokens encrypted only when a later provider API call needs them; request minimum scopes and provide disconnect plus another sign-in method before removing the last identity. Validate the OAuth state, preserve CSRF middleware, rate-limit entry points and log provider failures without tokens.

Model an identity separately from the user

An email is not a provider identifier. Store the immutable provider subject in an identity table with a unique composite key. It supports multiple providers, an email change and an explicit linking flow without guessing ownership.

php
<?php

declare(strict_types=1);

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::create('social_identities', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('user_id')->constrained()->cascadeOnDelete();
            $table->string('provider');
            $table->string('provider_id');
            $table->text('access_token')->nullable();
            $table->timestamps();
            $table->unique(['provider', 'provider_id']);
        });
    }
};

Keep callback decisions explicit

The redirect uses Socialite's stateful driver. At callback, look up the provider ID first; only an already authenticated user may attach a new identity. If a provider gives no verified email, show an account-completion flow rather than silently merging it with an existing account. Generate a password with Str::password() only where the schema still requires one, and create the application profile through the same UserObserver path as other users.

php
<?php

declare(strict_types=1);

namespace App\\Http\\Controllers\\Auth;

use Illuminate\\Http\\RedirectResponse;
use Laravel\\Socialite\\Facades\\Socialite;

final class SocialLoginController
{
    public function redirect(string $provider): RedirectResponse
    {
        return Socialite::driver($provider)->redirect();
    }
}

Tokens, recovery and test boundary

Encrypt tokens only when a later provider API call genuinely needs them; request the smallest scopes, never log tokens, provide disconnect and retain another recovery method before deleting the last identity. Use Socialite::fake() for feature tests of acceptance, cancellation, missing email and an existing password account. Pin a currently supported Meta Graph API version in config and review Meta's deprecation schedule during dependency maintenance.

Appendix: provider-console checklist

Create a web OAuth client, register the exact HTTPS callback URL for each environment, publish only scopes the feature needs, then test cancellation, denied consent, an existing password account and a provider without an email. Facebook Graph API versions are retired on a schedule: pin a currently supported version in config and plan its upgrade from Meta's changelog.

When not to use social login

Do not make a social provider the only recovery route for a business account. Do not auto-link an unverified email. For enterprise SSO, use OIDC/SAML with domain and lifecycle controls rather than treating consumer OAuth as employee identity.

Related articles

Existing system support

Need help with a live application?

I help companies improve live systems, clean up delivery workflows, and ship new features without adding avoidable complexity.

Comments (0)
Sign in to leave a comment

You need to be signed in to add a comment.

Login

Need someone to take responsibility for the next step?

Let’s talk about your project and define a scope that actually makes sense for your goals.