Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Socialiter Laravel Package

genealabs/laravel-socialiter

Socialiter adds social login to your Laravel app with minimal setup. Connect OAuth providers, link social accounts, and let users sign in with one click via Facebook, Google, GitHub, and more—all through a simple, configurable API that integrates cleanly with Laravel Socialite.

View on GitHub
Deep Wiki
Context7

Getting Started

1. Install and publish.

composer require genealabs/laravel-socialiter
php artisan vendor:publish --provider="GeneaLabs\LaravelSocialiter\Providers\SocialiterServiceProvider"
php artisan migrate

Two artifacts land in your app: config/socialiter.php (provider credentials, route/redirect settings) and a migration for the social-identity table. Read the published migration before running it — it is the package's only schema footprint and the thing you'll be diffing on every upgrade.

2. Where to look first, in this order:

  • config/socialiter.php — which providers are enabled, how the callback route is registered, and whether user creation is delegated to your app.
  • The published migration — table name, columns, unique constraints, and indexes on the provider/user lookup pair.
  • The Socialiter facade and the SocialAccount-style model — this is the entire public API surface; if you find yourself reaching past it, you're off the supported path.
  • The callback controller — you usually don't edit it, but you need to know what it does between "Socialite returns a user" and "session is authenticated."

3. Configure a provider. Put client ID/secret in config/services.php (Socialite's normal location) and enable the provider in config/socialiter.php. Set the OAuth redirect URI in the provider's console to match the route the package registers — this is the single most common first-run failure.

4. First use case: a login button.

<a href="{{ route('socialiter.redirect', 'github') }}">Sign in with GitHub</a>

Verify the actual route name against php artisan route:list | grep -i social. The flow is: redirect → provider → callback → package resolves or creates a User → you're authenticated. That's the whole vertical slice; get it green in a throwaway provider app (GitHub is the fastest to register) before wiring anything real.

Implementation Patterns

Provider-agnostic UI. Drive the button list off the config array rather than hardcoding providers. Adding Facebook later should be a config change plus credentials, not a template change:

@foreach (config('socialiter.providers') as $provider => $settings)
    @if (!empty($settings['client_id']))
        <a href="/auth/{{ $provider }}">Sign in with {{ ucfirst($provider) }}</a>
    @endif
@endforeach

Account linking for signed-in users. The high-value pattern is not "social login instead of passwords" — it's "social login alongside passwords." For an authenticated user, hit the same redirect endpoint but treat the callback as a link operation rather than a login. Since v13 no longer clobbers an existing password (PR #18), a user who signed up with email/password can add Google and keep both working. Store which provider(s) a user has, and render "Connected accounts" in account settings with an unlink action that deletes the social-identity row only — never the user.

Provisioning at first login via the user-creation callback (v13+, PR #19). This is the seam where product policy belongs. Register the callback in a service provider so that everything that must be true of a new OAuth user happens in one transaction-checked place:

// app/Providers/AppServiceProvider.php, boot()
Socialiter::createUserUsing(function ($socialiteUser, $provider) {
    return DB::transaction(function () use ($socialiteUser, $provider) {
        $user = User::create([
            'name'  => $socialiteUser->getName(),
            'email' => $socialiteUser->getEmail(),
            'role'  => 'member',
        ]);

        // invite gating, workspace/tenant assignment, CRM sync, terms acceptance
        $this->workspaces->assignDefault($user);

        return $user;
    });
});

Confirm the exact facade method name, argument order, and return contract against the published source for the tag you install — treat any extension point as undocumented until you've read it. Wrap the body in a transaction and make it idempotent-ish: if it throws after the package has written the identity row, you get an orphaned social account pointing at nothing.

Resolve, don't duplicate. Let the package answer "who is this GitHub user?" Call the facade/model rather than querying the social-identity table from controllers, policies, or Blade. A thin one-line wrapper in your own code (e.g. LinkedAccounts::forUser($user)) gives you a seam if the package's API shifts at the next major.

Test with Socialite's fake, not the network. Socialite ships Socialite::fake('github', $socialiteUser). Write three tests and keep them forever: (a) brand-new user via OAuth creates exactly one user + one identity row; (b) existing user's first social login does not modify their password; (c) a user with an existing link logs in and gets the same User id. These three cover the entire blast radius of what v13 changed.

Guard the callback route. Login-intent and link-intent hit the same controller. If you support linking, decide explicitly whether the callback checks Auth::check() and links versus logs in, and test the case where a signed-in user starts a link flow but the provider returns an email belonging to a different existing account. That's the account-takeover-shaped hole.

Gotchas and Tips

v13 migrations are the top risk — diff before you deploy. Laravel tracks migrations by filename. If v13's stubs were renamed, consolidated, or columns retyped (PR #17), php artisan migrate on an existing install will report "nothing to migrate" while a fresh install gets a different physical schema. Your upgraded production and your CI database will silently diverge. Mitigation, in order:

  1. Diff the v13 stub against the v12 stub and against your own database/migrations copy.
  2. Install v13 into a scratch database and mysqldump --no-data both it and a migrated-upgrade database; diff the dumps.
  3. If they differ, write a hand-authored remediation migration (rename/retype/index) rather than republishing stubs over an already-applied file.
  4. Check that the index backing your identity lookup survived the modernization — a schema tidy-up is exactly where an index vanishes unnoticed until p95 login latency degrades.

The password fix is a behavioral change, not a bugfix. Existing users who log in socially for the first time no longer get their password column overwritten. Any seeder, factory, QA script, or test asserting post-login password state will now fail — correctly. Also make sure your own code distinguishes null (no password set, social-only user) from a set password; don't render a "change password" form for the former, and don't treat null as "empty string."

Don't assume an email comes back. Not every provider returns one, and not every user has one public. If your users table requires a non-null unique email, a provider that omits it throws a QueryException deep inside a callback and surfaces as a 500 on the login path. Decide the policy up front: reject with a friendly error, or generate a placeholder. Handle the "social email already exists on another account" case explicitly too — auto-merging by email is an account-takeover vector when the provider doesn't verify emails.

Wrap your user-creation callback in a transaction. The package writes the social-identity row and your callback writes the User. A throw between them leaves a dangling identity with no user, and the next login attempt may resolve to it. DB::transaction() plus a cleanup job for orphaned identities is cheap insurance.

Prune tokens. If the package stores OAuth access/refresh tokens, they accumulate and expire. Nothing in the release notes says pruning is built in — verify, and if not, schedule your own php artisan command deleting rows older than the refresh window. This is your data, in your database, whether or not the package manages it.

Pin the major and clear config cache. "genealabs/laravel-socialiter": "^13.0" — deliberate, not floating, because this is a single-maintainer package (134 stars, no dependents listed, no commercial tier). After editing config/socialiter.php, run php artisan config:clear; a cached config is the second most common "I added a provider and nothing happened" cause, right behind a mismatched redirect URI.

Confirm the version matrix from composer.json in the tag. v13 announces Laravel 13 / PHP 8.5 support but doesn't state what it dropped. Check before you composer update, and schedule the runtime upgrade as its own workstream — don't let it ride along with a feature branch.

Don't fork migrations or depend on internals. The package's value is that it's removable. Direct queries against the identity/token table, subclassed package models, or edited migrations convert a one-day integration into a permanent maintenance obligation on a package with one maintainer. Bound the blast radius instead: thin wrapper, pinned version, rollback branch, and a per-provider synthetic-login smoke test running on a schedule so a provider-side OAuth change doesn't reach you via support tickets.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console