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

Yandex Laravel Package

socialiteproviders/yandex

Yandex OAuth provider for Laravel Socialite. Adds Yandex login to your Laravel app, letting users authenticate via their Yandex account using a familiar Socialite driver. Install via Composer and configure your client ID, secret, and redirect URI.

Deep Wiki
Context7

Getting Started

This is a read-only subtree split — the actual source of truth is SocialiteProviders/Providers under src/Yandex. Read Provider.php there first; the split repo mirrors it 1:1 and its 13 stars are just an artifact of the split.

Minimal install

composer require socialiteproviders/yandex

You get three packages pulled in: this provider, socialiteproviders/manager, and laravel/socialite.

1. Register credentials in config/services.php

'yandex' => [
    'client_id'     => env('YANDEX_CLIENT_ID'),
    'client_secret' => env('YANDEX_CLIENT_SECRET'),
    'redirect'      => env('YANDEX_REDIRECT_URI'),
],

2. Wire the Socialite event listener

Laravel ≤10 (app/Providers/EventServiceProvider.php):

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

Laravel 11/12 (no EventServiceProvider by default) — in AppServiceProvider::boot():

Event::listen(function (\SocialiteProviders\Manager\SocialiteWasCalled $event) {
    $event->extendSocialite('yandex', \SocialiteProviders\Yandex\Provider::class);
});

3. Register the app in Yandex OAuth console (oauth.yandex.ru → "Create app" → platform "Web services"). Add the exact callback URL, e.g. https://yourapp.test/auth/yandex/callback. Yandex requires the redirect host to match the app's registered domain.

First use case: a "Sign in with Yandex" button for a Russian/CIS audience — Socialite::driver('yandex')->redirect() out, ->user() back in the callback, then firstOrCreate on $user->getId() or $user->getEmail().

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

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

Implementation Patterns

Standard web flow with account creation

$yandexUser = Socialite::driver('yandex')->user();

$user = User::firstOrCreate(
    ['yandex_id' => $yandexUser->getId()],
    [
        'name'  => $yandexUser->getName() ?: $yandexUser->getNickname(),
        'email' => $yandexUser->getEmail(),
    ]
);
Auth::login($user);

Note $yandexUser->getId() is a string (Yandex user IDs overflow 32-bit ints) — store it as VARCHAR, not BIGINT, if you don't want surprises.

Custom scopes

The provider defaults to login:email and login:info. Override before redirect:

return Socialite::driver('yandex')
    ->scopes(['login:email', 'login:info', 'login:avatar'])
    ->redirect();

Use ->setScopes([...]) if you want to replace rather than merge.

Stateless (SPA / mobile / API)

Yandex supports the standard OAuth2 flow, so stateless works if you handle state yourself or accept the CSRF tradeoff:

return Socialite::driver('yandex')->stateless()->redirect();
// callback
$user = Socialite::driver('yandex')->stateless()->user();

Custom fields beyond the mapped object

mapUserToObject only maps id, nickname, name, email, avatar. Everything else lives in the raw payload — sex, birthday, default_phone, real_name, display_name, default_avatar_id, is_avatar_empty:

$raw = Socialite::driver('yandex')->user()->getRaw();
$birthday = $raw['birthday'] ?? null;

Calling other Yandex APIs

$user->token is a Yandex OAuth access token. Reuse it directly against Passport/Disk/Metrica:

Http::withToken($user->token)->get('https://login.yandex.ru/info', ['format' => 'json']);

Yandex endpoints accept both Authorization: Bearer <token> and Authorization: OAuth <token>. The provider itself uses OAuth.

Account linking

For an existing email/password app, don't firstOrCreate on email blindly — an attacker can register a Yandex account with your user's email. Verify $raw['default_email'] matches and require an authenticated session to link:

auth()->user()->update(['yandex_id' => $yandexUser->getId()]);

Testing

Socialite's AbstractProvider uses its own Guzzle client, so Http::fake() does not intercept it. Instead, mock at the Socialite boundary:

Socialite::shouldReceive('driver->user')->andReturn(
    (new \Laravel\Socialite\Two\User)->map(['id' => '123', 'email' => '[email protected]'])
);

Or build a Guzzle MockHandler stack and inject via Socialite::driver('yandex')->setHttpClient(...) if you need to test the provider mapping itself.

Gotchas and Tips

"Driver [yandex] is not supported." — the SocialiteWasCalled listener isn't registered, or you cached config/events. On Laravel 11+, $listen in a non-existent EventServiceProvider is silently ignored. Run php artisan event:clear && php artisan config:clear.

Redirect URI must match byte-for-byte. Trailing slash, http vs https, www vs apex — Yandex rejects mismatches with an opaque invalid_request, not a helpful message. For local dev, register http://localhost/auth/yandex/callback separately; 127.0.0.1 won't match localhost.

Config cache is the #1 "it works locally" bug. services.yandex is read at boot. Any env change needs php artisan config:clear. In CI or Docker builds where .env is baked, config:cache will freeze stale null credentials.

InvalidStateException almost always means the session died between redirect and callback — expired session, SESSION_DRIVER=array, multi-tab login, or a load balancer that doesn't stick sessions. Fix the infrastructure; don't blindly switch to stateless().

email can be null. If the user hasn't verified an email on Yandex, or you didn't request login:email, getEmail() returns null. If your users.email column is NOT NULL, that's a 500. Add login:email to scopes and handle the null case with an interstitial.

Avatar URL construction. The provider builds https://avatars.yandex.net/get-yapic/{default_avatar_id}/islands-200. When is_avatar_empty is true, default_avatar_id is absent — the mapped avatar becomes a broken URL. Check $raw['is_avatar_empty'] before rendering.

Yandex's id is a string and can exceed 2^31. If you scaffolded your migration as bigInteger, it'll overflow on some accounts. Use string / unsignedBigInteger with care — string is safest.

Don't file PRs here. The repo header says [READ ONLY] Subtree split. Open issues and PRs against SocialiteProviders/Providers; changes here are overwritten on the next split.

Version pinning is fuzzy. The split tags lag the monorepo. If you need a fix that landed upstream, you may need to composer require socialiteproviders/yandex:dev-main or override the provider class in your own Socialite::extend. The 2026-09-08 release date is auto-generated by the splitter, not a real commit date.

Extension point without forking. You can subclass SocialiteProviders\Yandex\Provider and override getAuthUrl, getTokenUrl, getUserByToken, or mapUserToObject, then register your subclass in the SocialiteWasCalled listener. Useful for adding PKCE, custom endpoints (oauth.yandex.com vs .ru), or extra mapped fields — no need to vendor the package.

Token refresh. The provider returns refresh_token in the raw token response, but Socialite won't refresh for you. Persist $user->refreshToken and $user->expiresIn yourself if you need long-lived access to Yandex APIs.

Rate limits. Yandex throttles /info per-token. Don't call it on every request just to check the profile — read the local user row instead.

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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
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