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 Odnoklassniki Laravel Package

jhaoda/socialite-odnoklassniki

Odnoklassniki (OK.ru) OAuth2 provider for Laravel Socialite. Adds OK.ru login to your app, letting users sign in with their Odnoklassniki account and fetch basic profile data through Socialite's familiar, fluent driver API.

View on GitHub
Deep Wiki
Context7

Getting Started

1. Install the provider

composer require jhaoda/socialite-odnoklassniki

The package ships with a Laravel service provider (Jhaoda\Socialite\Odnoklassniki\OdnoklassnikiServiceProvider) that is auto-discovered, so it typically registers itself without touching config/app.php. It extends Socialite's driver registry under the key odnoklassniki.

2. Register an OAuth app at OK.ru

Create an app at https://ok.ru/devaccess (or the equivalent "Мои приложения" section). You get back four values, all of which you need:

  • Client ID (application ID)
  • Client Secret (secret key)
  • Application Key (public key — not the same as the client ID; Odnoklassniki uses it to sign API calls)
  • Redirect URI — must be added verbatim in the app settings

3. Add credentials to config/services.php

'odnoklassniki' => [
    'client_id'       => env('ODNOKLASSNIKI_CLIENT_ID'),
    'client_secret'   => env('ODNOKLASSNIKI_CLIENT_SECRET'),
    'application_key' => env('ODNOKLASSNIKI_APPLICATION_KEY'),
    'redirect'        => env('ODNOKLASSNIKI_REDIRECT_URI'),
],

Note the extra application_key field — this is the thing people forget, and its absence produces opaque "invalid signature" errors rather than a clean config exception.

4. Two routes

// routes/web.php
Route::get('/auth/ok', fn () => Socialite::driver('odnoklassniki')->redirect());
Route::get('/auth/ok/callback', function () {
    $user = Socialite::driver('odnoklassniki')->user();
    // ->getId(), ->getNickname(), ->getName(), ->getEmail(), ->getAvatar()
});

First use case to try: a plain login button on an existing auth screen — redirect out, read getId() and getName() back, and log the raw $user->user array to see exactly which fields Odnoklassniki returned for your app's permission set. That raw dump is the fastest way to understand what you actually get before you design a users table around it.

Implementation Patterns

Standard stateless controller

public function redirect(): RedirectResponse
{
    return Socialite::driver('odnoklassniki')->redirect();
}

public function callback(Request $request): RedirectResponse
{
    try {
        $okUser = Socialite::driver('odnoklassniki')->user();
    } catch (\Throwable $e) {
        report($e);
        return redirect()->route('login')->withErrors('OK login failed.');
    }

    $user = User::updateOrCreate(
        ['odnoklassniki_id' => $okUser->getId()],
        [
            'name'   => $okUser->getName() ?: $okUser->getNickname(),
            'email'  => $okUser->getEmail(),
            'avatar' => $okUser->getAvatar(),
        ]
    );

    Auth::login($user, remember: true);
    return redirect()->intended('/dashboard');
}

Keep a dedicated nullable, indexed odnoklassniki_id column rather than overloading email as the identity key — email is frequently absent (see Gotchas).

Requesting scopes

Odnoklassniki uses uppercase scope tokens, and you pass them through Socialite's normal scopes() call:

return Socialite::driver('odnoklassniki')
    ->scopes(['VALUABLE_ACCESS', 'GET_EMAIL', 'LONG_ACCESS_TOKEN'])
    ->redirect();
  • VALUABLE_ACCESS — required to read profile data beyond the bare minimum
  • GET_EMAIL — the only way getEmail() returns anything
  • LONG_ACCESS_TOKEN — extends token life from ~30 minutes to a long-lived token
  • PHOTO_CONTENT — needed if you fetch the full-resolution avatar rather than the CDN thumbnail

Every scope you add must also be enabled for the app in the OK developer console, otherwise the consent screen silently drops it.

Stateless / API-style flows

If your frontend is a SPA, use ->stateless() on both legs and pass the code up from the client. Socialite's stateless mode works here, but you lose CSRF protection on the callback — pair it with your own signed-state check.

Account linking for existing users

For "connect your OK account" inside an authenticated session, don't log the user in from the callback. Instead resolve the identity, verify $okUser->getId() isn't already bound to a different local user, then attach:

if (User::where('odnoklassniki_id', $okUser->getId())
        ->whereKeyNot(auth()->id())->exists()) {
    return back()->withErrors('That OK account is already linked.');
}

auth()->user()->update(['odnoklassniki_id' => $okUser->getId()]);

Testing

Socialite's abstract driver is mock-friendly. Mock the driver at the facade level rather than hitting the network in CI:

Socialite::shouldReceive('driver->user')->andReturn(
    (new \Laravel\Socialite\Two\User)->map([
        'id' => '12345', 'name' => 'Ivan', 'email' => null, 'avatar' => '...',
    ])
);

If you need a real integration check, keep it in a separate, manually triggered test group — OK's endpoints are not something you want in a red/green loop.

Where to add customisation

The driver lives in vendor/jhaoda/socialite-odnoklassniki/src/. If you need extra profile fields (birthday, gender, locale, city), the cleanest route is to subclass the provider, register it under a new name with Socialite::extend('odnoklassniki_custom', ...) in a service provider, and override mapUserToObject(). Patching vendor files will not survive a composer update.

Gotchas and Tips

Email is usually null. Odnoklassniki treats email as sensitive. Without the GET_EMAIL scope and the corresponding permission granted to your app, getEmail() returns null. Design your schema and onboarding so email is optional for OK users, and prompt for it after registration instead of assuming it exists.

application_key is not client_id. The most common failure is pasting the client ID into the application_key slot. The driver signs API requests with an MD5 scheme combining sorted params, the client secret, and the app key; a wrong key yields generic "invalid signature" / "application not found" errors with no hint about which field is wrong. Double-check both values against the OK console.

OAuth tokens expire fast by default. Without LONG_ACCESS_TOKEN, the access token lives roughly 30 minutes. That's fine for one-shot login (you exchange the token immediately and discard it), but if you plan to poll the OK API later, request the long-lived scope up front — you cannot retroactively upgrade a short token without a fresh consent round-trip.

Redirect URI must match exactly. Odnoklassniki does not do wildcard or prefix matching at the app level. http:// vs https://, trailing slash, and www. differences all break the handshake, and the error surfaces at the callback rather than at redirect time, which makes it look like a token problem.

Package age and version compatibility. The last release is from March 2021, so verify it against your Socialite major version. If composer require resolves but you get Class "Jhaoda\...\OdnoklassnikiServiceProvider" not found or a driver-not-found error, check composer.json's extra.laravel.providers and, if auto-discovery failed, add the provider manually to config/app.php. If the package is incompatible with your Socialite version, the fallback is a ~50-line custom driver extending Laravel\Socialite\Two\AbstractProvider — the OK OAuth flow is simple enough that pinning an old socialite version usually isn't worth it.

Debugging checklist, in order: (1) dd($user->user) on the raw array — confirms scopes and field names; (2) confirm application_key is populated; (3) confirm the redirect URI in the console matches APP_URL byte-for-byte; (4) enable Socialite debug logging if the exception is swallowed. Almost every issue is one of those four.

Driver name is fixed. Socialite resolves the driver as odnoklassniki. If you register a custom subclass, don't reuse that name — you'll shadow the package's registration depending on provider load order. Use odnoklassniki_custom and reference it explicitly.

Don't trust getName() alone. Odnoklassniki returns both a display name and separate first_name/last_name fields, and which ones are populated depends on the user's privacy settings. Fall back through getName() → getNickname() → raw first_name . ' ' . last_name rather than rendering an empty greeting for users who hid their real name.

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.
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox