---
title: "Свързване с OAuth"
description: "Упълномощавайте MCP клиенти и ThunderPhone CLI, без да споделяте API ключ."
---

OAuth позволява на приложение да се свърже с една организация в ThunderPhone с одобрените от вас разрешения. Клиентите на директории трябва да използват OAuth по подразбиране. API ключовете на организацията остават налични за клиенти, които изискват ръчно конфигуриран Bearer токен.

## Одобряване на връзка

Стартирайте връзката във вашия MCP клиент. Влезте в ThunderPhone, проверете името на приложението и заявените разрешения, изберете организация и натиснете **Одобряване**. Изберете **Отказ**, ако не сте стартирали връзката или нямате доверие на приложението. Имената на приложенията се предоставят от техните разработчици и не са знак за проверка.

Разрешенията за четене предоставят достъп до посочените данни, включително записи и транскрипции, когато е заявено `calls:read`. Разрешенията за запис могат да променят или изтриват ресурси; обажданията, кампаниите, покупките на телефонни номера и внедряванията могат да доведат до разходи или да засегнат продукционната среда. Вашата роля в организацията продължава да се прилага.

За връзка чрез CLI отворете връзката за потвърждение, показана в терминала ви, сравнете осемзнаковия код, изберете организацията си и одобрете. Самото отваряне на връзката не предоставя достъп. Кодовете изтичат след 15 минути.

## Прекратяване на връзката с приложение

Отворете **Организация → API ключове → Упълномощени приложения** в таблото и изберете **Отмяна**. Това отменя избраното от вас упълномощаване за текущата организация, включително нейните токени за достъп и опресняване. Свържете се отново от приложението, ако искате да го упълномощите повторно.

## Откриване за MCP клиенти

Използвайте URL адреса на сървъра `https://api.thunderphone.com/v1/mcp`. Заявка без валидно удостоверяване получава `401` със:

```http
WWW-Authenticate: Bearer resource_metadata="https://api.thunderphone.com/.well-known/oauth-protected-resource"
```

Извлечете този документ, след което извлечете метаданните на сървъра за оторизация от `https://api.thunderphone.com/.well-known/oauth-authorization-server`. Метаданните за ресурса са достъпни и на `/.well-known/oauth-protected-resource/v1/mcp`. Използвайте върнатите крайни точки, вместо да ги конструирате. Идентификаторът на ресурса е `https://api.thunderphone.com/v1/mcp`.

Сървърът поддържа код за оторизация със **S256 PKCE**, ротация на токени за обновяване, публична динамична регистрация на клиент, анулиране и предоставяне на оторизация за устройство. Не се използват тайни на клиента или неявни предоставяния. OpenID откриването също е налично на `/.well-known/openid-configuration`; то включва същите полета за сървъра за оторизация, плюс `subject_types_supported: ["public"]` и крайната точка за потребителска информация. ID токени и документи с метаданни за Client ID (CIMD) не се поддържат.

### Регистриране на публичен клиент

Изпратете JSON към `POST /v1/oauth/register`:

```json
{
  "client_name": "My MCP client",
  "redirect_uris": ["http://127.0.0.1:8765/callback"],
  "token_endpoint_auth_method": "none",
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"]
}
```

Запазете върнатия `client_id`. Пренасочванията трябва да използват HTTPS или HTTP на `127.0.0.1` или `localhost`. Регистрирайте точния URI за обратно извикване, включително неговия порт и път. Фрагменти и вградени идентификационни данни се отхвърлят. Незадължителните `client_uri` и `logo_uri` трябва да използват HTTPS; ThunderPhone не ги извлича по време на регистрацията. Регистрацията е ограничена по честота. Регистрираните клиенти не изтичат и остават регистрирани, когато връзка бъде анулирана. HTTPS обратните извиквания включват `https://chatgpt.com/connector/oauth/<id>` и `https://chatgpt.com/connector_platform_oauth_redirect`. Всяка връзка може да регистрира собствен клиент.

### Код за оторизация

Отворете откритата крайна точка за оторизация с `client_id`, точния регистриран `redirect_uri`, `response_type=code`, произволен `state`, `scope`, `code_challenge`, `code_challenge_method=S256` и `resource=https://api.thunderphone.com/v1/mcp`. Изчислете предизвикателството като SHA-256 хеш в base64url без допълване на нов PKCE верификатор с висока ентропия. Проверете върнатите `state` и `iss`, преди да обмените кода. Всеки отговор за оторизация, включително при отказ и грешки в протокола, идентифицира издателя чрез `iss`, който трябва точно да съвпада с открития `issuer`. Грешките за невалиден клиент или обратно извикване се връщат локално без пренасочване към това обратно извикване.

Обменете чрез `POST /v1/oauth/token`, използвайки кодиране на формуляр (приема се и JSON):

```text
grant_type=authorization_code
client_id=<your client id>
code=<single-use authorization code>
redirect_uri=<exact registered redirect URI>
code_verifier=<original PKCE verifier>
resource=https://api.thunderphone.com/v1/mcp
```

Незадължителният параметър `resource` се приема както при заявки за оторизация, така и при заявки за токен (включително при обмен за обновяване и за устройство). Когато липсва, по подразбиране използва открития MCP ресурс. Когато присъства, той трябва точно да съвпада с този ресурс; други стойности връщат `invalid_target`. Токените за достъп съдържат тази аудитория, а MCP отхвърля токени с липсваща или различна аудитория с `401` и предизвикателство за откриване.

Заявките за оторизация и кодовете изтичат след 10 минути. Всеки отговор за токен съдържа `access_token`, `token_type` (`Bearer`), `expires_in` (3600 секунди по подразбиране), `refresh_token`, `scope`, `organization_id` и `organization_name`. Изпращайте токените за достъп само чрез заглавката `Authorization: Bearer`. Никога не поставяйте токени в URL адреси, регистрационни записи, контрол на версиите или чат.

### Обновяване и анулиране

Обновявайте с `grant_type=refresh_token`, `client_id`, `refresh_token` и `resource` в крайната точка за токени. Запазвайте новия токен за обновяване атомарно и спрете да използвате стария. Токените за обновяване изтичат след 30 дни без успешно обновяване. Незадължителният `scope` може да ограничи предоставените разрешения. `offline_access` винаги е включен и винаги се издават токени за обновяване. Първоначална заявка без `scope` предоставя само `offline_access`, затова клиентите трябва да заявяват необходимите им разрешения.

Повторното използване на код и повторното използване на ротиран токен за обновяване анулират цялата оторизация. Сериализирайте обновяванията в рамките на клиент; повторното изпращане на успешно обменени идентификационни данни не е безопасна стратегия за повторен опит.

За да прекъснете връзка, изпратете `token` и `client_id` към `POST /v1/oauth/revoke`. Анулирането на който и да е токен анулира неговата оторизация, включително всички токени, издадени от него. Непознат токен връща успех, без да разкрива дали съществува. Сесиите в таблото могат да изброят собствените си оторизации чрез `GET /v1/oauth/grants` и да анулират една чрез `DELETE /v1/oauth/grants/<id>`, като `X-ThunderPhone-Org` избира организацията.

### Оторизация за устройство

Оторизацията за устройство е ограничена до предварително регистрирани клиенти; динамично регистрираните клиенти получават `unauthorized_client`. Предварително регистрираният публичен клиент `thunderphone-cli` поддържа оторизация за устройство и обновяване. Изпратете `client_id=thunderphone-cli` и `scope` към `POST /v1/oauth/device/code`. Покажете на потребителя `user_code` и `verification_uri` или отворете `verification_uri_complete`.

Анкетирайте крайната точка за токени с `grant_type=urn:ietf:params:oauth:grant-type:device_code`, `client_id` и `device_code`, като изчаквате поне върнатия `interval` (5 секунди). Продължете при `authorization_pending`. При `slow_down` използвайте новия `interval`, върнат в отговора (увеличен с 5 секунди), за всяка следваща заявка. Спрете при `access_denied`, `expired_token` или друга грешка. Никога не одобрявайте код за устройство автоматично.

Предварително регистрираният клиент `thunderphone-mcp` приема `http://127.0.0.1/callback` и `http://localhost/callback` на всеки порт. Схемата, хостът, пътят и заявката трябва да съвпадат; обменът на токен трябва да използва точния URI за пренасочване (включително порта) от оторизацията. Динамично регистрираните клиенти изискват точно съвпадение на URI за пренасочване, включително порта. Регистрирайте динамично различно обратно извикване, ако ви е необходим друг път.

### Проверки на идентичността на акаунта и домейна на работното пространство

Заявете едновременно `openid email` и обхватите за операциите, от които клиентът ви се нуждае. Извикайте открития `userinfo_endpoint` (`GET /v1/oauth/userinfo`) с токена за достъп в заглавката Bearer. Успешният отговор съдържа:

```json
{
  "sub": "123",
  "email": "person@example.com",
  "email_verified": true,
  "name": "Example User",
  "org_id": 456
}
```

`sub` е стабилният идентификатор на потребителя; `org_id` е организацията, избрана при съгласието. Крайната точка изисква и двата обхвата за идентичност и връща `403`, ако някой от тях липсва. Тя връща `403` с `error=access_denied`, ако акаунтът няма профил с потвърден имейл, вместо да твърди, че непотвърден имейл е надежден. Невалидни, изтекли, анулирани или с грешна аудитория токени връщат `401`. Токените за човешки сесии и API ключовете на организации не могат да извикват userinfo. Не се издава ID токен.

## Налични разрешения

| Категория | Обхвати |
| --- | --- |
| Агенти и импортирания на агенти | `agents:read`, `agents:write` |
| Обаждания | `calls:read`, `calls:write` |
| Телефонни номера и VoIP | `numbers:read`, `numbers:write` |
| Знания | `knowledge:read`, `knowledge:write` |
| Кампании | `campaigns:read`, `campaigns:write` |
| Интеграции, крайни точки за webhook, MCP сървъри | `integrations:read`, `integrations:write` |
| Гласове | `voices:read` |
| Тестови сценарии, тестови изпълнения, валидиране | `testing:read`, `testing:write` |
| Фактуриране | `billing:read` |
| Идентичност на акаунта и потвърден имейл | `openid`, `email` (и двата са задължителни за userinfo) |
| Постоянна връзка | `offline_access` (винаги е включен) |

GET, HEAD и OPTIONS използват обхвати за четене; другите методи използват обхвати за запис. Промени на гласове и фактуриране не са достъпни чрез OAuth; `POST /v1/voices/preview` използва `voices:read`, защото визуализира глас, без да променя конфигурацията му. MCP инструментите прилагат обхвата на основната си REST операция. Прехвърлянията между организации се отказват дори когато потребителят, който дава разрешение, принадлежи към двете организации. Други API категории, включително управление на API ключове и настройки на човешки акаунти, не са достъпни чрез OAuth. Липсващо разрешение за REST операция връща `403` с `WWW-Authenticate: Bearer error="insufficient_scope", scope="..."`. Невалидните или изтеклите токени за достъп връщат `401`.


### Сигнали за удостоверяване на MCP инструменти

Всеки инструмент в `tools/list` включва `securitySchemes: [{"type": "oauth2", "scopes": ["agents:read"]}]`, с обхвата на REST операцията на съответния инструмент. Публичните инструменти за документация използват празен списък с обхвати и все пак изискват удостоверена връзка.

Валиден токен, в който липсва обхватът на даден инструмент, получава HTTP `200` с JSON-RPC `result`, съдържащ `isError: true`, пояснителен текст в `content` и `_meta["mcp/www_authenticate"]`. Последното е масив, съдържащ Bearer предизвикателство с `resource_metadata`, `error="insufficient_scope"`, `error_description` и изисквания `scope`. Инструментът не се изпълнява. Използвайте това предизвикателство, за да заявите разширено съгласие. Липсващо или невалидно удостоверяване продължава да връща HTTP `401` с `WWW-Authenticate`; неуспешните REST проверки за обхват продължават да връщат HTTP `403`.

## Съхранение на идентификационни данни

API изпълнява `python manage.py oauth_cleanup` на всеки час в средата за тестване и продукционната среда. Командата премахва изтекли заявки за удостоверяване и кодове за устройства. Изтеклите токени за достъп, кодове за удостоверяване и хешове на токени за обновяване се премахват едва след като предоставеното разрешение бъде отменено или цялото семейство стане невалидно. Използваните хешове се съхраняват, докато семейството разполага с използваем токен за обновяване, код за удостоверяване, одобрен код за устройство или токен за достъп, така че почистването да не може да деактивира откриването на повторно използване.
