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

Sentinel Social Laravel Package

cartalyst/sentinel-social

Adds social OAuth login to Cartalyst Sentinel, letting users sign in with Facebook, Google, Twitter and other providers while their accounts persist through Sentinel's user repository. Extends Sentinel's authentication flow with social provider support for Laravel applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Prerequisite: this package is only worth installing when Cartalyst Sentinel is already the source of truth for users in your app. It does not extend Auth::guard(); it resolves an OAuth identity and hands it back to Sentinel's own repositories, hashing, session persistence, and throttling. If you are on Breeze/Jetstream/Fortify or plain Auth, stop here — you would be adding a second auth stack for no gain.

Minimal path to a working Google login:

  1. Confirm Sentinel works first. Sentinel::authenticate([...]), Sentinel::login($user), and Sentinel::check() should already be running in your app before you touch this package. Everything in Sentinel Social assumes those are healthy.
  2. Install and pin. Cartalyst packages historically live behind a private repo/credentials, and the license resolves as NOASSERTION — get legal clearance before you spend engineering time. Pin an exact version and commit composer.lock:
    composer require cartalyst/sentinel-social:6.1.1
    
  3. Read the source before the README. With effectively no docs and 0 stars, orientation comes from four places: composer.json (PHP/Laravel/Sentinel constraints — this is your compatibility truth, not the release note), src/ (the service provider plus the SocialManager-style class you'll call), resources/config/ (the provider registry you edit), and src/Provider/ (the template a custom provider must match).
  4. Register the provider and publish the config. Laravel auto-discovery may not cover it; add it explicitly if php artisan vendor:publish --provider="..." finds nothing. Then fill in client_id, client_secret, and the exact callback URL per provider.
  5. First use case — "Sign in with Google". Two routes, two controller methods:
    // routes/web.php
    Route::get('auth/{provider}', [SocialController::class, 'redirect']);
    Route::get('auth/{provider}/callback', [SocialController::class, 'callback']);
    
    // SocialController
    public function redirect(string $provider)
    {
        session(['social.provider' => $provider]);
        return SentinelSocial::with($provider)->redirect();
    }
    
    public function callback()
    {
        $provider = session()->pull('social.provider');
    
        try {
            $user = SentinelSocial::with($provider)->authenticate();
        } catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) {
            report($e);
            return redirect()->route('login')->withErrors('Social sign-in failed.');
        }
    
        if (! $user) {
            return redirect()->route('register.social'); // link or register flow
        }
    
        Sentinel::login($user, true);
        return redirect()->intended('/dashboard');
    }
    
  6. Get Google or GitHub end-to-end before adding a second provider. They have the least fussy consent screens and reliable email claims. Facebook and Twitter are where the edge cases live.

Implementation Patterns

Model the three intents explicitly, even if you only ship one. The manager exposes intent methods rather than a single login() — expect authenticate() (resolve provider user → find linked Sentinel user → return it or null), a register()-style path (create a Sentinel user from provider data), and a separate linking path for an already-authenticated Sentinel user. Build all three routes in the first release. Retrofitting "attach my Google account" after users have already registered with passwords means reconciling email collisions in production, which is far more expensive than wiring the route up front.

Treat the manager as a credential source, not a user-provisioning system. Sentinel Social should answer "who is this OAuth user?" — your app still owns activation, roles, and onboarding. After a register() succeeds, run your normal pipeline:

$user->roles()->attach(Sentinel::findRoleBySlug('member')->id);
// dispatch welcome mail, fire your NewUserRegistered event, etc.

Do not let the package's defaults decide whether a social user is active. On most Sentinel setups a freshly created user is inactive until activated — verify this explicitly, or nobody can log in and you'll spend an afternoon on it.

Custom providers are the actual headline feature. If you're integrating a regional or enterprise IdP, you write a class, not a fork:

// app/Social/Provider/AcmeProvider.php
class AcmeProvider extends \League\OAuth2\Client\Provider\AbstractProvider
{
    public function getBaseAuthorizationUrl() { /* ... */ }
    public function getBaseAccessTokenUrl(array $params) { /* ... */ }
    public function getResourceOwnerDetailsUrl(AccessToken $token) { /* ... */ }

    protected function createResourceOwner(array $response, AccessToken $token)
    {
        return new AcmeResourceOwner($response); // normalize: uid, email, name
    }
}

Register it under providers in the published config with a short key, then call it by key: SentinelSocial::with('acme')->authenticate(). Keep the provider class free of Sentinel logic — token exchange and user normalization only. That separation is what makes the class testable and the manager swappable.

Route layout that scales. A /{provider} prefix with an allow-list beats one route pair per provider. Resolve the provider from the configured registry and 404 on anything not registered — never pass an arbitrary string to with().

Store provider intent in the session, not the callback query string. A ?provider=google on the callback is user-controlled and pairs badly with state validation. Set it on redirect, pull it on callback.

Abstract the manager behind your own interface. Live OAuth round-trips in CI are slow and flaky. Define SocialAuthenticator in your app, bind it to a thin wrapper around the package manager, and swap in a fake returning a canned Sentinel user in tests. This also gives you a single seam to replace the package later without touching controllers.

Tokens are not your problem — until they are. The package resolves identity; it does not persist access/refresh tokens for you to call the provider's API later. If you anticipate "post to Facebook on the user's behalf", capture the token in the callback yourself and store it encrypted. Deciding this after launch means re-prompting every user for consent.

Gotchas and Tips

  • Callback URL mismatch is the #1 failure and it is byte-for-byte. http vs https, www vs bare, trailing slash, port, and subdomain all count. Behind a load balancer, TrustProxies and APP_URL must be right or Laravel generates a redirect URI the provider rejects as redirect_uri_mismatch. Log the exact generated URI once and diff it against the console.
  • State validation depends on the session. The League client's CSRF state store is session-backed. If your redirect route and callback route sit in different middleware groups or on different session domains (e.g. api vs web), state checks fail and the error looks unrelated to sessions. Keep both routes in web.
  • Never mix Auth::login() with Sentinel::login(). Sentinel has its own session keys and Sentinel::check(). Code that assumes Auth::user() will return null after a social login and you'll chase it for hours.
  • Handle a missing email. Facebook in particular may return no email (unverified account, or the user declined the scope). Never write null into a unique email column — branch to an explicit "confirm your email" step. Same for email collisions: a Google login with an email that already exists as a password account should route to the link flow, not silently create a duplicate or auto-merge.
  • OAuth1 ≠ OAuth2. Twitter-style providers use a different League base class and different config keys. Do not copy an OAuth2 provider class as a template — it will half-work and fail at token exchange.
  • Config caching bites env(). If you publish the config, php artisan config:cache after every change, and note that any env() inside it is baked at cache time. Read secrets in config, never in provider classes.
  • Debug from the raw exception, not the user-facing message. invalid_grant, redirect_uri_mismatch, expired codes, and denied consent all surface identically as IdentityProviderException to the user. Log $e->getMessage() and the response body; add a request ID so support can correlate a user report with a log line.
  • Pin and plan an exit. Last release is February 2021, the sole visible change is a dev-dependency cleanup (league/oauth2-facebook fork → upstream), there are zero dependents, and the license is NOASSERTION. Verify the Composer constraints against your PHP/Laravel before adopting, and assume you may need to fork when a League OAuth2 major moves. Keeping the manager behind your own interface is what makes that a weekend rather than a quarter.
  • Extension points, not vendor edits. If you need something the manager lacks — unlink(), custom user resolution, a different persistence path — extend the manager and rebind the container binding in your own service provider. Editing vendor/ guarantees you lose the change on the next composer update.
  • Check that throttling still applies. Sentinel's login throttling lives in authenticate(). A social callback that resolves a user and calls Sentinel::login() directly may bypass it entirely — verify and apply throttling yourself if so.
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.
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle