OAuth2Аутентификация OAuth2

OAuth2

Аутентификация OAuth2

Позвольте другим аккаунтам Sofia подключать ваше приложение: зарегистрируйте клиент, пройдите authorization code flow с PKCE, обновляйте токены и scopes.

OAuth: authorization code с PKCE

Зарегистрируйте клиент в Настройки › API › Клиенты приложений: название, логотип, политика конфиденциальности, разрешения, которые он может запрашивать, и https-адреса перенаправления. У конфиденциального клиента есть секрет; у публичного (мобильное приложение, расширение браузера) его нет, и он опирается только на PKCE.

Отправьте человека на эндпоинт авторизации с PKCE-challenge (S256 обязателен) и state, который вы храните в его сессии:

javascript
import { createHash, randomBytes } from 'node:crypto';

const verifier = randomBytes(32).toString('base64url');
const challenge = createHash('sha256').update(verifier).digest('base64url');
const state = randomBytes(16).toString('base64url');

const url = new URL('https://api.sofia-post.com/api/v1/oauth/authorize');
url.search = new URLSearchParams({
  response_type: 'code',
  client_id: process.env.SOFIA_CLIENT_ID,
  redirect_uri: 'https://app.example.com/oauth/callback',
  scope: 'establishments:read posts:read posts:write offline_access',
  state,
  code_challenge: challenge,
  code_challenge_method: 'S256',
}).toString();

Человек входит в Sofia, видит ваше название, логотип и разрешения, выбирает Workspace и подтверждает. Затем Sofia возвращает его на ваш адрес перенаправления с code, вашим state и издателем iss. Проверьте оба значения и обменяйте code:

bash
curl -X POST https://api.sofia-post.com/api/v1/oauth/token \
  -u "$SOFIA_CLIENT_ID:$SOFIA_CLIENT_SECRET" \
  -d grant_type=authorization_code \
  -d code=$CODE \
  -d redirect_uri=https://app.example.com/oauth/callback \
  -d code_verifier=$VERIFIER
json
{
  "access_token": "sofia_live_at_…",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "establishments:read posts:read posts:write offline_access",
  "refresh_token": "sofia_live_rt_…"
}
  • Code действует 5 минут и только один раз. При повторном использовании он отклоняется, а выданные по нему токены перестают работать.
  • Access-токен живёт один час и действует только в выбранном человеком Workspace.
  • refresh_token возвращается, только если вы запросили offline_access. Он одноразовый: каждый раз сохраняйте новый. Повторное использование уже использованного refresh-токена отзывает всю авторизацию.
bash
curl -X POST https://api.sofia-post.com/api/v1/oauth/token \
  -u "$SOFIA_CLIENT_ID:$SOFIA_CLIENT_SECRET" \
  -d grant_type=refresh_token \
  -d refresh_token=$REFRESH_TOKEN

OAuth: client credentials

Конфиденциальный клиент может также действовать в Workspace, которым владеет его владелец, без участия человека. Если у клиента несколько Workspace, укажите нужный через workspace_id.

bash
curl -X POST https://api.sofia-post.com/api/v1/oauth/token \
  -u "$SOFIA_CLIENT_ID:$SOFIA_CLIENT_SECRET" \
  -d grant_type=client_credentials \
  -d workspace_id=$WORKSPACE_ID

Разрешения (scopes)

ScopeПозволяет
establishments:readПолучать список заведений
accounts:read, accounts:writeЧитать подключённые сети; создавать ссылки для подключения
media:read, media:writeЧитать медиатеку; загружать и импортировать медиа
posts:read, posts:writeПолучать список публикаций и следить за ними; публиковать, изменять и удалять
insights:readЧитать статистику
webhooks:read, webhooks:writeПолучать список webhook; регистрировать, тестировать и удалять их
offline_accessТолько OAuth: получить refresh-токен

Вызов без нужного scope отвечает 403 insufficient_scope. Метаданные сервера (RFC 8414) перечисляют все эндпоинты и scopes:

text
https://api.sofia-post.com/.well-known/oauth-authorization-server/api/v1/oauth