Подключенные приложения и OAuth
B1 API поддерживает OAuth 2.0, поэтому приложение третьей стороны может попросить разрешение администратора каждой церкви на доступ к их данным — без необходимости церкви делиться паролем или API ключом. Подключенное приложение — это OAuth токен, одобренный администратором церкви; отзыв его прерывает доступ приложения третьей стороны одним щелчком. Используйте этот путь для многопользовательских соединителей SaaS. Для интеграции с одной церковью предпочитайте API ключи.
Перед началом
- OAuth клиент должен быть зарегистрирован (в настоящее время администратором сервера B1) перед тем, как церкви смогут предоставить ему доступ
- Все конечные точки OAuth находятся под модулем Membership:
/membership/oauth/... - Токены доступа — это JWTs — они содержат разрешения пользователя, отфильтрованные по предоставленным областям
Концепции
| Термин | Значение |
|---|---|
| OAuth клиент | Само приложение третьей стороны — идентифицируется по client_id, защищено по client_secret. Зарегистрировано один раз с B1, общее для всех церквей, которые его установят. |
| Подключенное приложение | Конкретная пара (client, church-admin), где администратор предоставил клиенту доступ. Каждое подключенное приложение поддерживается OAuth токеном обновления. |
| Токен доступа | Коротко-живущий JWT (≈ 7 дней), который клиент использует для вызовов API. То же самое, что пользовательский JWT — Authorization: Bearer <jwt>. |
| Токен обновления | Долго-живущая непрозрачная строка (≈ 90 дней), которую клиент использует для выпуска новых токенов доступа. |
| Область | Сужает то, что может делать токен доступа — см. каталог областей. |
Потоки предоставления
B1 поддерживает три потока OAuth, все определенные RFC 6749 + RFC 8628.
Код авторизации (веб-приложения)
Используйте, когда ваше приложение имеет компонент на стороне сервера и может держать client_secret в приватном режиме.
-
Авторизация
POST /membership/oauth/authorize
Authorization: Bearer <user JWT>
Content-Type: application/json
{ "client_id": "...", "redirect_uri": "https://app.example.com/cb",
"response_type": "code", "scope": "people:read groups:read", "state": "xyz" }Возвращает
{ "code": "...", "state": "xyz" }. Конечная точка авторизационного кода намеренно является аутентифицированным POST — ваше приложение собирает JWT B1 пользователя (обычно путем размещения кнопки в сессии B1 пользователя) и передает его как часть шага согласия. -
Обменять код на токены
POST /membership/oauth/token
Content-Type: application/json
{ "grant_type": "authorization_code", "code": "...",
"client_id": "...", "client_secret": "...", "redirect_uri": "..." }Возвращает ответ токена:
{
"access_token": "eyJ...",
"token_type": "Bearer",
"expires_in": 604800,
"created_at": 1715000000,
"refresh_token": "abc123…",
"scope": "people:read groups:read"
} -
Обновить, когда токен доступа вот-вот истекает:
POST /membership/oauth/token
Content-Type: application/json
{ "grant_type": "refresh_token", "refresh_token": "...",
"client_id": "...", "client_secret": "..." }Токен обновления истекает после 90 дней неиспользования; если он истек, администратор церкви переавторизуется.
Код устройства (телевизоры, киоски, CLI)
Используйте, когда устройство не имеет браузера. Определено RFC 8628.
-
Запросить код устройства
POST /membership/oauth/device/authorize
Content-Type: application/json
{ "client_id": "...", "scope": "content:read" }Возвращает код, обращенный к пользователю и интервал опроса:
{ "device_code": "...", "user_code": "WXYZ-1234",
"verification_uri": "https://app.b1.church/device",
"expires_in": 900, "interval": 5 } -
Отобразите
user_code+verification_uriпользователю. -
Опрашивать
/membership/oauth/tokenсgrant_type=urn:ietf:params:oauth:grant-type:device_codeиdevice_code. Стандартные ответы:Ошибка Значение authorization_pendingПользователь еще не одобрил — продолжайте опрашивать с предложенным интервалом expired_tokenКод устройства уже прошел expires_in— начните зановоaccess_deniedПользователь отклонил запрос (нет — 200 OK) Одобрено — тело — это B1TokenResponse -
После одобрения сохраните
refresh_tokenи используйтеaccess_tokenдо истечения его срока действия.
B1 SDK включает B1OAuthClient.awaitDeviceToken(...), который запускает цикл опроса для вас с рассудительной отсрочкой, соответствующей RFC.
Токен обновления
Всегда доступно как самостоятельный запрос, как только у вас есть refresh_token:
POST /membership/oauth/token
{ "grant_type": "refresh_token", "refresh_token": "...", "client_id": "..." }
Возвращаются новые access_token и refresh_token. Открытые клиенты (нет client_secret) могут опустить client_secret на обновление — полезно для мобильных/настольных приложений OAuth, которые не могут держать секрет.
Формат токена
Токен доступа — это выданный B1 JWT, идентичный тому, который пользователь получит от POST /membership/users/login — то же модульное право требовать, то же поведение checkAccess в каждом контроллере — за исключением, что массив разрешений был отфильтрован через предоставленные области во времени выпуска. Токен доступа с областью не может делать ничего, что не может делать аналогично ограниченный API ключ, и нет отдельного «пути OAuth» ни в одном контроллере; actionWrapper не знает, является ли носитель человеком, API ключом или OAuth клиентом.
Подключенные приложения (ориентированные на пользователя)
С точки зрения администратора церкви, "Подключенные приложения" — это список приложений, которым был предоставлен доступ к их церкви. Каждая строка — это живая пара (OAuthClient, OAuthToken).
В B1Admin: Параметры → Разработчик → Подключенные приложения показывает:
- Имя клиента
- Области, которые администратор одобрил
- Дату, когда был предоставлен доступ
- Кнопку Отозвать
| Метод и путь | Auth | Назначение |
|---|---|---|
GET /membership/oauth/connections | JWT | Список активных подключений вызывающего (объединенный с именем клиента + области) |
DELETE /membership/oauth/connections/:id | JWT | Отозвать подключение по его ID токена OAuth — токен прекратит работать на следующий запрос |
Список автоматически исключает истекшие токены.
Области и согласие
Строки область — это тот же самый каталог, что и API ключи. Лучшие практики для клиентов:
- Запрашивайте самые узкие области, которые работают. Церкви замечают, если вы запрашиваете
donations:write, когда вам нужно только читать людей. - Используйте токен обновления плюс короткие токены доступа. Долгоживущие токены доступа труднее отозвать быстро.
- Всегда представляйте предоставленные области обратно пользователю в вашем собственном пользовательском интерфейсе, чтобы они могли проверить, на что они согласились.
Управление OAuth клиентом
OAuth клиенты (сами приложения третьих сторон) в настоящее время регистрируются глобально администратором сервера B1. Самостоятельная регистрация для каждой церкви находится в дорожной карте — до тех пор, чтобы доставить открытый соединитель, вы обращаетесь в команду ChurchApps для выпуска пары client_id / client_secret и регистрации ваших redirect URIs.
| Метод и путь | Разрешение | Описание |
|---|---|---|
GET /membership/oauth/clients | Server.Admin | Список всех OAuth клиентов |
GET /membership/oauth/clients/clientId/:clientId | — | Получить клиента по его открытому id (секрет замаскирован) |
POST /membership/oauth/clients | Server.Admin | Создать или обновить клиента |
DELETE /membership/oauth/clients/:id | Server.Admin | Удалить клиента |
Поддержка SDK
Пакет @churchapps/integration-sdk оборачивает каждый поток OAuth с типизированными помощниками — B1OAuthClient.exchangeCode(), .refresh(), .startDeviceFlow(), .pollDeviceToken(), .awaitDeviceToken(). Посмотрите README пакета и Webhooks для сквозного примера.