OAuth 2.0 / RFC 6749

Единая авторизация SpecHelp ↔ Блог Инженера

Документация и спецификация двухстороннего SSO между Блогом Инженера и экосистемой цифровых решений SpecHelp (Spec ID, ТестКонтроль, Форум, ЕИСОТ).

Ключи доступа (OAuth 2.0 Credentials)

Используются на стороне Блога Инженера для подключения входа через Spec ID.

Client ID
blog_ingenera
Client Secret
spk_sec_YOUR_CLIENT_SECRET
Зарегистрированный Redirect URI (Белый список)
https://blog-ingenera.w.manu.team/wp-json/ingener/v1/social/auth/spechelp
* Также предварительно добавлен боевой домен: https://blog-ingenera.ru/wp-json/ingener/v1/social/auth/spechelp
🧪 Тестовый аккаунт Spec ID для проверки
Активен
Email (Логин)
manuteam@spec.help
Пароль
ManuTeam2026!
Используйте этот аккаунт для отладки входа через Spec ID: он уже зарегистрирован и готов к тестированию через /oauth/authorize.

💡 Связывание аккаунтов (Account Linking по Email)

Вопрос: Если у пользователя уже есть аккаунт с таким Email в Блоге Инженера на момент входа через SpecHelp, сохраняется ли старый вход по паролю?

Ответ: Да, сохраняются оба способа!
В эндпоинте /oauth/userinfo всегда передаётся "email_verified": true. На стороне WordPress-контроллера Блога при получении профиля выполняется поиск get_user_by('email', $email). Если пользователь найден, его ID связывается с профилем SpecHelp. Пользователь сможет входить в Блог и по своему существующему логину/паролю Блога, и в 1 клик через кнопку «Войти через SpecHelp».

Схема Authorization Code Flow

Классический безопасный протокол OAuth 2.0 (RFC 6749) с обменом через серверный бэкенд.

1
Запрос авторизации
Пользователь переходит на /oauth/authorize. Входит в Spec ID и подтверждает доступ для Блога.
2
Редирект с кодом
Spec ID перенаправляет обратно на ваш redirect_uri с одноразовым кодом ?code=...&state=....
3
Обмен на бэкенде
Сервер Блога запрашивает POST /oauth/token, получает access_token и забирает профиль из /oauth/userinfo.
GET https://id.specstage.ru/oauth/authorize
Инициирует сеанс входа. Если пользователь не авторизован в Spec ID, он увидит форму логина, после чего — экран подтверждения передачи данных в «Блог Инженера».
Параметры строки запроса (Query Parameters)
Параметр Тип Статус Описание / Значение
client_id string Обязательный blog_ingenera
redirect_uri string Обязательный URL колбэка на вашей стороне. Должен быть URL-encoded.
response_type string Обязательный Всегда code
scope string Опционально openid profile email (по умолчанию)
state string Рекомендуется Случайная строка защиты от CSRF. Будет возвращена в неизменном виде.
Пример ссылки для кнопки «Войти через SpecHelp»
https://id.specstage.ru/oauth/authorize?client_id=blog_ingenera&redirect_uri=https%3A%2F%2Fblog-ingenera.w.manu.team%2Fwp-json%2Fingener%2Fv1%2Fsocial%2Fauth%2Fspechelp&response_type=code&state=xyz123
POST https://id.specstage.ru/oauth/token
Обменивает авторизационный код на Bearer Access Token. Вызывается только с бэкенда Блога Инженера. Поддерживает application/json, application/x-www-form-urlencoded, а также передачу реквизитов в заголовке Authorization: Basic.
Параметры тела запроса (Request Body)
Параметр Тип Статус Описание
client_id string Обязательный blog_ingenera
client_secret string Обязательный Секретный ключ проекта
code string Обязательный Код из параметра $_GET['code'], время жизни 2 минуты
redirect_uri string Обязательный Должен в точности совпадать с переданным на первом шаге
Пример cURL запроса
curl -X POST https://id.specstage.ru/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "blog_ingenera",
    "client_secret": "spk_sec_YOUR_CLIENT_SECRET",
    "code": "4b8c9f02...",
    "redirect_uri": "https://blog-ingenera.w.manu.team/wp-json/ingener/v1/social/auth/spechelp"
  }'
Успешный ответ (HTTP 200 OK)
{
  "access_token": "spk_3f8a92cb412d0891a27e0...",
  "token_type": "Bearer",
  "expires_in": 86400,
  "scope": "openid profile email"
}
GET https://id.specstage.ru/oauth/userinfo
Возвращает верифицированный профиль пользователя, контактные данные, имя и привязанные права в экосистеме.
Заголовки запроса (HTTP Headers)
Заголовок Значение Описание
Authorization Bearer {access_token} Токен, полученный на шаге /oauth/token
Пример ответа (HTTP 200 OK)
{
  "id": 1054,
  "sub": "1054",
  "email": "ivan.petrov@example.com",
  "email_verified": true,
  "name": "Иван Петров",
  "first_name": "Иван",
  "last_name": "Петров",
  "display_name": "Иван Петров",
  "username": "ivan_petrov",
  "avatar": "https://id.specstage.ru/files/avatars/avatar.png",
  "phone": "+79991234567",
  "is_pro": true,
  "pro_expiration_date": "2027-03-15",
  "entitlements": {
    "pro_active": true,
    "pro_expires_at": "2027-03-15",
    "eisot_access": true,
    "forum_access": true
  }
}

Вход в Spec ID через Блог Инженера

Авторизация пользователей в Spec ID через аккаунт Блога Инженера.

На странице входа https://id.specstage.ru/login уже размещена фирменная кнопка «Войти через Блог—Инженера™ (PRO)».

1
Открытие попапа Блога
Spec ID открывает попап авторизации: https://blog-ingenera.w.manu.team/oauth/authorize?client_id=...&redirect_to=https://id.specstage.ru
2
postMessage код
Попап передает одноразовый код через window.opener.postMessage(code, origin) и закрывается.
3
Обмен и PRO-статус
Spec ID бэкенд запрашивает POST /wp-json/ingener/v1/oauth/code, забирает профиль и мгновенно активирует PRO-статус.