Документация разработчика

Интегрируйте единый вход через QQ ID в свое веб-приложение. Наша платформа полностью соответствует стандартам OAuth 2.1 и OpenID Connect (OIDC), делая авторизацию защищенной, современной и быстрой.


Введение

QQ ID реализует современную спецификацию OAuth 2.1. Это означает, что:

  • PKCE (Proof Key for Code Exchange) обязателен для всех клиентов. В отличие от классического OAuth 2.0, здесь нельзя авторизоваться без отправки криптографического подтверждения.
  • Не поддерживается небезопасный метод Implicit Grant (токен в хэше URL) и метод передачи паролей Resource Owner Password Credentials.
  • Используется строгое совпадение зарегистрированных адресов перенаправления (redirect_uri).
⚠️ Важное примечание: Базовый домен для API запросов и OIDC авторизации — https://id.qqxx.ru. Все ссылки интеграции должны вести на этот домен.

1. Регистрация приложения

Перед началом работы вам необходимо зарегистрировать приложение в личном кабинете разработчика:

  1. Перейдите в Кабинет разработчика (требуется авторизация).
  2. Нажмите кнопку «Создать приложение».
  3. Укажите название вашего сервиса, домашнюю страницу и список разрешенных Redirect URIs (например, https://my-app.ru/callback).
  4. После создания скопируйте уникальный идентификатор client_id (начинается с app_).

2. Генерация параметров PKCE

PKCE защищает авторизационный код от перехвата. Вам необходимо сгенерировать два параметра:

  • code_verifier — случайная криптографическая строка длиной от 43 до 128 символов (состоящая из букв, цифр, дефиса, точки, подчеркивания и тильды).
  • code_challenge — закодированный в Base64Url хэш SHA-256 от строки code_verifier.
js
// 1. Генерация случайного code_verifier
function generateVerifier() {
  const array = new Uint32Array(56);
  window.crypto.getRandomValues(array);
  return Array.from(array, dec => ('0' + dec.toString(16)).substr(-2)).join('');
}

// 2. Хеширование SHA-256 и Base64Url кодирование для code_challenge
async function generateChallenge(verifier) {
  const encoder = new TextEncoder();
  const data = encoder.encode(verifier);
  const hash = await window.crypto.subtle.digest('SHA-256', data);
  return btoa(String.fromCharCode(...new Uint8Array(hash)))
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=+$/, '');
}

const verifier = generateVerifier();
const challenge = await generateChallenge(verifier);
console.log({ verifier, challenge });

3. Запрос авторизации (Redirect)

Перенаправьте пользователя на страницу входа QQ ID. Вы должны составить URL со следующими query-параметрами:

http
https://id.qqxx.ru/oauth/authorize?
  client_id=app_82f1bc8f9b...&
  redirect_uri=https://yoursite.ru/callback&
  response_type=code&
  scope=openid+profile+email&
  state=YOUR_RANDOM_STATE&
  code_challenge=CODE_CHALLENGE_HERE&
  code_challenge_method=S256

Описание параметров запроса

ПараметрОбязателенОписание
client_idДаИдентификатор вашего приложения, полученный при регистрации.
redirect_uriДаАдрес перенаправления. Должен точно совпадать с одним из зарегистрированных в панели.
response_typeДаВсегда фиксирован: code.
scopeДаСписок запрашиваемых прав доступа через пробел (или знак +):
openid — признак OIDC авторизации
profile — доступ к имени, никнейму и аватару
email — доступ к адресу электронной почты
offline_access — если нужен refresh_token для работы в оффлайн режиме
stateДаСлучайная строка для защиты от CSRF. Проверяйте её равенство на своей стороне при callback.
code_challengeДаСтрока PKCE challenge, сгенерированная на 2-м шаге.
code_challenge_methodДаВсегда строго: S256. Использование plain запрещено.

4. Обмен кода на токены

После успешного входа QQ ID перенаправит пользователя на указанный redirect_uri с параметрами code и state:

http
GET https://yoursite.ru/callback?code=AUTH_CODE_HERE&state=YOUR_RANDOM_STATE

Убедитесь, что полученный state равен исходному значению. После этого отправьте POST-запрос с типом контента application/x-www-form-urlencoded на адрес https://id.qqxx.ru/oauth/token для обмена кода на токены.

🔒 Важная информация по безопасности: Этот запрос должен отправляться только с вашего бэкенд-сервера, а не из браузера. Никогда не раскрывайте ваш code_verifier на клиенте.
http
POST /oauth/token HTTP/1.1
Host: id.qqxx.ru
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&
code=AUTH_CODE_HERE&
client_id=YOUR_CLIENT_ID&
code_verifier=YOUR_ORIGINAL_CODE_VERIFIER&
redirect_uri=https://yoursite.ru/callback

Пример успешного JSON-ответа

json
{
  "access_token": "eyJhbGciOiJSUzI1NiIs...",
  "id_token": "eyJhbGciOiJSUzI1NiIs...",
  "refresh_token": "rt_8a2d1f7c...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "openid profile email"
}

5. Получение профиля пользователя

Для получения свежих персональных данных авторизованного пользователя выполните GET-запрос к endpoint https://id.qqxx.ru/oauth/userinfo, передав access_token в заголовке Authorization:

http
GET /oauth/userinfo HTTP/1.1
Host: id.qqxx.ru
Authorization: Bearer ACCESS_TOKEN_HERE

Пример ответа UserInfo

json
{
  "sub": "2f40b2a8-8e6f-4fb6-a4c4-72a39281a8f6",
  "email": "user@example.com",
  "email_verified": true,
  "name": "Иван Иванов",
  "preferred_username": "ivan_dev",
  "picture": "https://id.qqxx.ru/static/uploads/avatars/default.png",
  "locale": "ru",
  "updated_at": 1781415000
}

6. Локальная проверка подписи JWT (OIDC)

Токены id_token и access_token являются JWT-токенами, подписанными алгоритмом RS256 (асимметричный ключ RSA-2048). Вы можете проверить подпись токена без обращения к нашему серверу.

  1. Скачайте набор открытых ключей JWKS по адресу: https://id.qqxx.ru/.well-known/jwks.json
  2. Извлеките заголовок JWT токена и найдите идентификатор ключа (kid).
  3. Найдите соответствующий ключ в JWKS по полю kid.
  4. Проверьте подпись токена с помощью RSA-2048, используя параметры n (modulus) и e (exponent).
  5. Убедитесь, что поле iss (issuer) строго равно https://id.qqxx.ru, токен не истек (exp) и поле aud совпадает с вашим client_id.

7. Интеграция с помощью JavaScript SDK

Если вы хотите реализовать вход на стороне фронтенда без сложной серверной разработки, вы можете использовать наш официальный JavaScript SDK.

Пример интеграции кнопки на HTML-странице

html
<!-- 1. Контейнер для кнопки входа -->
<div id="qqid-btn-container"></div>

<!-- 2. Инициализация SDK -->
<script type="module">
  import { QQId } from 'https://id.qqxx.ru/sdk/qq-id.js';

  const auth = new QQId({
    clientId: 'YOUR_CLIENT_ID',
    redirectUri: 'https://yoursite.ru/callback'
  });

  // Встраивание брендовой адаптивной кнопки входа
  auth.renderButton('#qqid-btn-container', {
    theme: 'dark', // 'dark' | 'light'
    size: 'large', // 'small' | 'medium' | 'large'
    width: 280
  });

  // Проверка сессии при загрузке страницы
  const user = auth.getUser();
  if (user) {
    console.log('Пользователь уже авторизован:', user);
  }
</script>

Обработка callback на странице возврата

html
<!-- На странице https://yoursite.ru/callback -->
<script type="module">
  import { QQId } from 'https://id.qqxx.ru/sdk/qq-id.js';

  const auth = new QQId({
    clientId: 'YOUR_CLIENT_ID',
    redirectUri: 'https://yoursite.ru/callback'
  });

  // Автоматически обрабатывает query параметры callback и выполняет обмен
  auth.handleCallback()
    .then((session) => {
      console.log('Авторизация успешна!', session.user);
      // Перенаправьте на внутренний дашборд
      window.location.href = '/dashboard';
    })
    .catch((err) => {
      console.error('Ошибка входа QQ ID:', err);
    });
</script>