VK ID API: Сделать вход через VK ID на сайте

Сценарий из mcp-everything. Актуально на 2026-10-24.

Кнопка «Войти через VK ID»: пользователь входит без пароля, сайт получает его имя, аватар и, если разрешено, телефон и email.

  1. Создай приложение в кабинете VK ID и укажи redirect_uri. Для каждого входа сгенерируй code_verifier (43–128 символов), code_challenge — base64url от SHA-256 code_verifier — и state (не меньше 32 символов). Сохрани code_verifier и state в сессии.
  2. Отправь пользователя на GET /authorize с response_type = code, client_id, redirect_uri, state, code_challenge, code_challenge_method = S256 и scope (по умолчанию vkid.personal_info; телефон и email — отдельные права). provider = ok_ru или mail_ru открывает вход через Одноклассники или Mail.ru.
  3. На redirect_uri придут code (живёт 10 минут), device_id и state. Сравни state с сохранённым — иначе отклони запрос.
  4. Обменяй код на токены: POST /oauth2/auth с grant_type = authorization_code, code, code_verifier, redirect_uri, client_id, device_id и state (form-urlencoded). В ответе access_token (живёт час), refresh_token, id_token и user_id.
  5. Получи профиль: POST /oauth2/user_info с client_id и access_token — user_id, first_name, last_name, avatar, а также phone и email, если они есть в правах токена.
import base64, hashlib, secrets, requests
from urllib.parse import urlencode

CLIENT_ID, REDIRECT = "<client_id>", "https://example.ru/auth/vk/callback"

# 1–2. Начало входа
verifier = secrets.token_urlsafe(64)[:96]
challenge = base64.urlsafe_b64encode(hashlib.sha256(verifier.encode()).digest()).rstrip(b"=").decode()
state = secrets.token_urlsafe(32)
session.update(vk_verifier=verifier, vk_state=state)
login_url = "https://id.vk.ru/authorize?" + urlencode({
    "response_type": "code", "client_id": CLIENT_ID, "redirect_uri": REDIRECT, "state": state,
    "code_challenge": challenge, "code_challenge_method": "S256", "scope": "vkid.personal_info email"})

# 3–5. Обработчик redirect_uri
def callback(args):
    if args["state"] != session["vk_state"]:
        raise PermissionError("state mismatch")
    tokens = requests.post("https://id.vk.ru/oauth2/auth", data={
        "grant_type": "authorization_code", "code": args["code"], "code_verifier": session["vk_verifier"],
        "redirect_uri": REDIRECT, "client_id": CLIENT_ID, "device_id": args["device_id"], "state": args["state"],
    }).json()
    user = requests.post("https://id.vk.ru/oauth2/user_info",
                         data={"client_id": CLIENT_ID, "access_token": tokens["access_token"]}).json()["user"]
    return tokens, user

Базовые URL

Авторизация

Тип: OAuth 2.0

Пользователь проходит GET /authorize и возвращается на redirect_uri с code и device_id; код обменивается на access_token, refresh_token и id_token методом POST /oauth2/auth. PKCE обязателен: code_verifier — 43–128 символов, code_challenge — base64url от SHA-256 строки code_verifier. Access token действует 1 час.

Методы сценария

GET /authorize — Код подтверждения и форма разрешений

При успехе — редирект на redirect_uri с code (живёт 10 минут), device_id и state; при ошибке — JSON с error и error_description.

Параметр Где Тип Обяз. Описание
response_type query string да code
client_id query string да ID приложения
redirect_uri query string да Адрес возврата
state query string да Случайная строка, не меньше 32 символов
code_challenge query string да Хэш code_verifier
code_challenge_method query string да S256
scope query string нет Права, по умолчанию vkid.personal_info
prompt query string нет none, login, consent
provider query string нет vkid, ok_ru, mail_ru
lang_id query string нет Язык интерфейса
scheme query string нет light или dark

POST /oauth2/auth — Обмен кода на токены

grant_type=authorization_code. В ответе: access_token, refresh_token, id_token, token_type, expires_in, user_id, state, scope.

Параметр Где Тип Обяз. Описание
grant_type body string да authorization_code
code body string да Код из редиректа
code_verifier body string да Исходная строка PKCE
redirect_uri body string да Тот же адрес возврата
client_id body string да ID приложения
device_id body string да device_id из редиректа
state body string да Строка state
service_token body string нет Для конфиденциальных приложений
ip body string нет IP пользователя

POST /oauth2/auth — Обновление токенов

grant_type=refresh_token. Возвращает новую пару access_token и refresh_token (без id_token); старая пара инвалидируется.

Параметр Где Тип Обяз. Описание
grant_type body string да refresh_token
refresh_token body string да Refresh-токен
client_id body string да ID приложения
device_id body string да ID устройства
state body string да Строка state
scope body string нет Права
service_token body string нет Для конфиденциальных приложений
ip body string нет IP пользователя

POST /oauth2/user_info — Данные пользователя (без маскирования)

В user: user_id, first_name, last_name, avatar, sex, verified, birthday; phone и email — если в токене есть соответствующие права.

Параметр Где Тип Обяз. Описание
client_id body string да ID приложения
access_token body string да Access-токен

Нюансы

Другие сценарии


Если этого недостаточно — официальная документация: https://id.vk.ru/about/business/go/docs/ru/vkid/latest/vk-id/connection/api-description Вся интеграция одним документом: https://mcp-everything.ru/integrations/vk-id.md