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

Socialite Mailru Laravel Package

jhaoda/socialite-mailru

A Laravel Socialite provider for Mail.ru authentication. This package adds a Mail.ru OAuth driver so users can sign in with their Mail.ru accounts through Socialite’s familiar, simple API.

View on GitHub
Deep Wiki
Context7

Getting Started

1. Install

composer require jhaoda/socialite-mailru

2. Register an OAuth app with Mail.ru

Create an app at the Mail.ru OAuth console (https://o2.mail.ru/app/). You get a Client ID and Client Secret, and you must register an exact Redirect URI, e.g. https://myapp.test/auth/mailru/callback. Mail.ru is strict about the URI matching (scheme, host, path, trailing slash) — set one per environment.

3. Configure credentials

config/services.php:

'mailru' => [
    'client_id'     => env('MAILRU_CLIENT_ID'),
    'client_secret' => env('MAILRU_CLIENT_SECRET'),
    'redirect'      => env('MAILRU_REDIRECT_URI'),
],

.env:

MAILRU_CLIENT_ID=
MAILRU_CLIENT_SECRET=
MAILRU_REDIRECT_URI="${APP_URL}/auth/mailru/callback"

4. Register the driver

Laravel 5.5+ package discovery may register the package's service provider automatically — check vendor/jhaoda/socialite-mailru/composer.json for an extra.laravel.providers entry first. If there isn't one, add the provider class to config/app.php (providers array) or register it manually in AppServiceProvider::boot(), which is the most version-proof route:

use Laravel\Socialite\Contracts\Factory as SocialiteFactory;
use Jhaoda\Socialite\Mailru\MailruProvider;

public function boot(SocialiteFactory $socialite)
{
    $socialite->extend('mailru', function ($app) use ($socialite) {
        $config = $app['config']['services.mailru'];

        return new MailruProvider(
            $app['request'],
            $config['client_id'],
            $config['client_secret'],
            $config['redirect']
        );
    });
}

Confirm the exact provider FQCN against vendor/jhaoda/socialite-mailru/src — the namespace casing (Mailru vs MailRu) is the usual first stumbling block.

5. First use case: "Sign in with Mail.ru"

// routes/web.php
Route::get('/auth/mailru/redirect', fn () =>
    \Laravel\Socialite\Facades\Socialite::driver('mailru')->redirect()
)->middleware('guest');

Route::get('/auth/mailru/callback', [MailruAuthController::class, 'callback']);
public function callback()
{
    $mailruUser = Socialite::driver('mailru')->user();

    $user = User::firstOrCreate(
        ['email' => $mailruUser->getEmail()],
        ['name'  => $mailruUser->getName() ?: $mailruUser->getNickname()]
    );

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

    return redirect()->intended('/dashboard');
}

That round-trip — redirect out, callback in, user() mapped to your users table — is the whole package in day-to-day use.

Implementation Patterns

Thin controller, dedicated service. Keep the redirect/callback pair in a small controller and push account resolution into an action or service class. The provider is just an HTTP adapter; your identity logic should not live next to it.

Provider-agnostic identity table. Store provider + provider_user_id in a social_accounts table rather than trusting email as the key. Mail.ru id is a stable string; email can change or be absent.

$account = SocialAccount::firstOrCreate(
    ['provider' => 'mailru', 'provider_user_id' => $mailruUser->getId()],
    ['user_id' => $user->id]
);

Account linking / merge flow. If a user already exists with the same email, link the Mail.ru identity to that account instead of creating a duplicate. Because Mail.ru is a major Russian identity provider, many of your users will already have a local account.

Token-based flow for SPA / mobile. If your front end obtains a Mail.ru access token itself, use the stateless path so no session state is round-tripped:

$user = Socialite::driver('mailru')->stateless()->userFromToken($request->bearerToken());

This relies on the provider's getUserByToken() hitting Mail.ru's userinfo endpoint with a bearer token — verify it works against a real token before committing to it, since the package is old.

Request extra scopes explicitly. Mail.ru returns limited profile data by default. If you need the email address, request it:

Socialite::driver('mailru')->scopes(['email'])->redirect();

Also configure it once globally if every login needs it:

$provider = Socialite::driver('mailru');
$provider->setScopes(['userinfo', 'email']);

Handle the user object exactly once. Socialite::driver() builds a fresh provider each call, so calling user() twice hits Mail.ru twice. Assign it to a variable and pass it around.

Testing. Socialite isn't faked by Http::fake() (it uses its own Guzzle client), so mock at the container level:

$this->mock(\Laravel\Socialite\Contracts\Factory::class, function ($mock) {
    $driver = \Mockery::mock(\Laravel\Socialite\Contracts\Provider::class);
    $driver->shouldReceive('user')->andReturn($this->fakeMailruUser());
    $mock->shouldReceive('driver')->with('mailru')->andReturn($driver);
});

Error-friendly callback route. Wrap the callback body in try/catch and redirect back to login with a flash message on InvalidStateException, ClientException, or a null user. Users who hit "Cancel" on the Mail.ru consent screen arrive at your callback with error=access_denied, not a user object.

Extension point. If Mail.ru changes endpoints or returns new fields, subclass the provider and override getAuthUrl(), getTokenUrl(), or getUserByToken(), then register the subclass in Socialite::extend. Don't edit the vendor files — keep the override in app/.

Gotchas and Tips

Package age is the biggest risk. Last release is March 2021, so its illuminate/support constraints likely predate Laravel 9/10/11. Run composer require jhaoda/socialite-mailru and, if it fails, composer why-not jhaoda/socialite-mailru. Options in order of preference: fork and widen the constraints, write a ~60-line custom provider yourself (the OAuth2 flow is trivial), or use Socialite::extend with the package's provider class while skipping its service provider. With 23 stars and zero dependents, budget for the package being unmaintained.

"Driver [mailru] is not supported". Almost always a registration problem, not a credential problem. The service provider wasn't auto-discovered, or you're running in a context (queue worker, artisan command) where the provider didn't boot. Re-check config/app.php / package discovery and make sure you cleared the config cache.

InvalidStateException on callback. Socialite stores the OAuth state in the session. Causes: session driver misconfigured across subdomains, the user opened the callback URL directly, a load balancer sending the callback to a different node with a non-shared session store, or SESSION_DOMAIN/SESSION_SECURE_COOKIE not matching your HTTPS setup. It also fires if you used stateless() on the redirect but not the callback (or vice versa).

Email may be missing. Mail.ru only returns the address when the email scope is granted, and the user can decline. Never make email a NOT NULL requirement for Mail.ru signups — fall back to nickname + provider ID and prompt for an email afterward.

The id is a string, often long. Store provider_user_id as VARCHAR(64), not BIGINT. Casting to int on 32-bit PHP or a loose column type will silently truncate and merge unrelated users.

Config cache. After adding services.mailru, run php artisan config:clear (or config:cache in deploy). A stale cached config produces "missing client_id" / null-credential errors that look like Mail.ru rejecting you.

Redirect URI must match byte-for-byte. Mail.ru (like most providers) compares the redirect_uri in the token exchange against the registered value. http vs https, www vs bare domain, and a trailing slash all count. Behind a proxy or load balancer, don't generate the URI dynamically from url()->current() — pin it in MAILRU_REDIRECT_URI.

Hardcoded endpoints. The provider pins oauth.mail.ru URLs. If Mail.ru deprecates a path or you need a sandbox/test tenant, you cannot change it via config — subclass and override.

Wrap network calls. user() can throw a Guzzle ClientException on a 4xx from Mail.ru (expired code, reused code). Catch \Throwable in the callback and fail gracefully rather than 500-ing on the login page.

Don't log or expose the secret. Common mistake is dumping the whole provider/config in exception handlers. Also keep the client_secret out of JS bundles if you do a SPA token flow — exchange codes server-side.

Avatar URLs are not guaranteed. Mail.ru may return an empty or http:// image URL. Treat it as optional, and download/re-host it server-side rather than hotlinking in production templates.

Vendor risk mitigation. MIT license means you can fork freely. If this is load-bearing auth, vendor the provider class into your app now and keep the package as a reference — you'll be maintaining it either way, and owning the code makes Socialite major-version upgrades much easier.

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.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums