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

Laravelpassport Laravel Package

socialiteproviders/laravelpassport

Laravel Passport OAuth provider for Laravel Socialite. Adds a passport driver so your app can authenticate users against any Laravel Passport server using standard OAuth2 flows, with minimal setup and familiar Socialite syntax.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the provider and its manager alongside Socialite:

composer require laravel/socialite socialiteproviders/manager socialiteproviders/laravelpassport

On the Passport server (the identity provider), create an authorization-code client — the ones passport:install generates are password and personal grant clients and are not what Socialite needs:

php artisan passport:client --redirect_uri="https://client-app.test/auth/laravelpassport/callback"

Note the client_id and client_secret it prints.

On the client app, add the service config in config/services.php (the host key is the provider's required addition — it points at the Passport server root, no path):

'laravelpassport' => [
    'client_id'     => env('LARAVELPASSPORT_CLIENT_ID'),
    'client_secret' => env('LARAVELPASSPORT_CLIENT_SECRET'),
    'redirect'      => env('LARAVELPASSPORT_REDIRECT_URI'),
    'host'          => env('LARAVELPASSPORT_HOST'), // e.g. https://id.example.com
],

If you're on an older socialiteproviders/manager, register the event listener manually in app/Providers/EventServiceProvider.php; on current versions the package's service provider is auto-discovered and wires up LaravelPassportExtendSocialite for you:

protected $listen = [
    \SocialiteProviders\Manager\SocialiteWasCalled::class => [
        \SocialiteProviders\LaravelPassport\LaravelPassportExtendSocialite::class.'@handle',
    ],
];

First use case — the classic two-route flow:

Route::get('/auth/redirect', fn () => Socialite::driver('laravelpassport')->redirect());

Route::get('/auth/callback', function () {
    $user = Socialite::driver('laravelpassport')->user();
    // $user->id, ->name, ->email, ->getRaw()
});

The callback hits the server's /oauth/token, then the provider calls /api/user with the bearer token — that endpoint must exist on the Passport app (the stock Laravel routes/api.php route is fine) and be protected by auth:api.

Implementation Patterns

Central SSO across multiple Laravel apps. Treat one Passport app as the identity provider and every other app as a client. Each client gets its own client_id/client_secret/redirect and points host at the same server. The identity provider stays authoritative for users; clients typically just Auth::login($user) after looking up or provisioning a local record by $user->id or $user->email.

Local user resolution on callback. The provider returns a Laravel\Socialite\Two\User, not a logged-in session user. Pattern:

$remote = Socialite::driver('laravelpassport')->user();

$user = User::firstOrCreate(
    ['email' => $remote->email],
    ['name' => $remote->name, 'password' => Str::random(40)]
);

Auth::login($user, remember: true);

Scoping and statelessness. Default scope is *; narrow it per route with ->scopes(['profile']) before redirect(). For API-to-API or SPA flows where you can't carry a session, call ->stateless() on both legs and match the state yourself (or accept the risk only over trusted channels).

Extending the provider when the default contract doesn't fit. The provider assumes fixed endpoints (/oauth/authorize, /oauth/token, /api/user) and a user payload with id, name, email. If your server returns extra fields or nests the user, subclass and override:

namespace App\Socialite;

use SocialiteProviders\LaravelPassport\Provider as BaseProvider;

class Provider extends BaseProvider
{
    protected function getUserByToken($token)
    {
        $response = $this->getHttpClient()->get($this->host.'/api/v1/me', [
            'headers' => [
                'Accept' => 'application/json',
                'Authorization' => 'Bearer '.$token,
            ],
        ]);

        return json_decode($response->getBody(), true);
    }

    protected function mapUserToObject(array $user)
    {
        return (new \Laravel\Socialite\Two\User)->setRaw($user)->map([
            'id'       => $user['uuid'],
            'name'     => $user['display_name'],
            'email'    => $user['email'],
            'nickname' => $user['username'] ?? null,
            'avatar'   => $user['avatar_url'] ?? null,
        ]);
    }
}

Then register your subclass against the laravelpassport driver name in a Socialite::extend or a custom SocialiteWasCalled listener.

Token handling. The provider hands back the raw token response in $user->getRaw() / $user->token. If the client app needs to call the Passport server's API on the user's behalf, persist access_token, refresh_token, and expires_in and refresh with a standard OAuth2 client — Socialite itself won't refresh for you.

Multi-environment config. Because host is a plain config value, you can swap identity servers per environment (staging IdP vs. production IdP) without code changes. Validate at boot that host is absolute and matches the redirect URI's registered client — a mismatch silently produces a invalid_client at the token step.

Gotchas and Tips

host is the root, not the authorize URL. Setting host to https://id.example.com/oauth produces https://id.example.com/oauth/oauth/authorize. It must be https://id.example.com. Trailing slashes on host can also create //oauth/authorize — trim it in config or via a cast.

Use passport:client, not passport:install. passport:install creates personal-access and password-grant clients. Authorization-code grants (what Socialite uses) require php artisan passport:client --redirect_uri=... with the exact callback URL. Passport enforces exact string equality on redirect URIs — a missing trailing slash or http vs https fails at the token exchange, not at redirect, which makes it look like a token bug.

Register the listener if auto-discovery is off. In apps with shouldDiscoverEvents() disabled or package discovery stripped, the provider will silently fall through to "Driver [laravelpassport] not supported". That's the error to look for — it means the SocialiteWasCalled listener never fired.

/api/user is a hardcoded assumption. If the Passport app doesn't expose an API route returning the authenticated user, or it returns 401 because the api guard isn't using the Passport driver, you get a ClientException from getUserByToken. Verify config/auth.php has 'driver' => 'passport' on the api guard and that User implements Laravel\Passport\HasApiTokens.

Scope * requires wildcard support. Passport will error with invalid_scope if the client requests a scope the server doesn't define and wildcard scopes aren't registered. Either call ->scopes([...]) with real scopes or ensure the Passport Passport::tokensCan() set includes what you send.

Debugging the two HTTP calls. The common failure points are distinct: redirect failures are almost always a bad authorize URL or unregistered redirect URI; callback failures are almost always token exchange (wrong secret, expired code, mismatched redirect) or /api/user (missing route, wrong guard, non-JSON response). Log $e->getResponse()->getBody() from Socialite's InvalidStateException / ClientException — the raw body carries Passport's error code, which is much more useful than the exception message.

Extension points. Override getAuthUrl, getTokenUrl, getUserByToken, mapUserToObject, or getTokenFields in a subclass if the identity server deviates from stock Passport. getTokenFields is handy when Passport is behind a proxy that needs extra parameters, but be careful — Passport's oauth/token is strict about unknown fields in some versions.

Compatibility. Last release was mid-2022 and the package tracks Socialite's Two\AbstractProvider. Pin laravel/socialite and socialiteproviders/manager together, and run the redirect flow in a fresh install before layering on custom providers — the manager's event-listener registration has changed across majors, and a mismatch shows up as "driver not supported" rather than a clear version error.

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