---
title: "Conectați-vă cu OAuth"
description: "Autorizați clienții MCP și interfața CLI ThunderPhone fără a partaja o cheie API."
---

OAuth permite unei aplicații să se conecteze la o organizație ThunderPhone cu permisiunile pe care le aprobați. Clienții de director ar trebui să utilizeze OAuth în mod implicit. Cheile API ale organizației rămân disponibile pentru clienții care necesită un token Bearer configurat manual.

## Aprobați o conexiune

Începeți conexiunea în clientul MCP. Autentificați-vă în ThunderPhone, verificați numele aplicației și permisiunile solicitate, alegeți o organizație și selectați **Aprobă**. Selectați **Respinge** dacă nu ați inițiat conexiunea sau nu aveți încredere în aplicație. Numele aplicațiilor sunt furnizate de dezvoltatorii acestora și nu reprezintă o insignă de verificare.

Permisiunile de citire expun datele indicate, inclusiv înregistrările și transcrierile atunci când este solicitat `calls:read`. Permisiunile de scriere pot modifica sau șterge resurse; apelurile, campaniile, achizițiile de numere de telefon și implementările pot genera costuri sau pot afecta mediul de producție. Rolul dumneavoastră în organizație se aplică în continuare.

Pentru o conexiune CLI, deschideți linkul de verificare afișat în terminal, comparați codul din opt caractere, selectați organizația și aprobați. Simplul fapt că deschideți linkul nu acordă acces. Codurile expiră după 15 minute.

## Deconectați o aplicație

Deschideți **Organizație → Chei API → Aplicații autorizate** în tabloul de bord și alegeți **Revocă**. Aceasta revocă autorizarea selectată pentru organizația curentă, inclusiv tokenurile sale de acces și de reîmprospătare. Reconectați-vă din aplicație dacă doriți să o autorizați din nou.

## Descoperire pentru clienți MCP

Utilizați URL-ul serverului `https://api.thunderphone.com/v1/mcp`. O solicitare fără autentificare validă primește `401` cu:

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

Preluați acel document, apoi preluați metadatele serverului de autorizare la `https://api.thunderphone.com/.well-known/oauth-authorization-server`. Metadatele resursei sunt disponibile și la `/.well-known/oauth-protected-resource/v1/mcp`. Utilizați endpointurile returnate în loc să le construiți. Identificatorul resursei este `https://api.thunderphone.com/v1/mcp`.

Serverul acceptă codul de autorizare cu **S256 PKCE**, tokenuri de reîmprospătare rotative, înregistrarea dinamică a clienților publici, revocarea și fluxul de autorizare pentru dispozitive. Nu există secrete de client sau fluxuri implicite. Descoperirea OpenID este disponibilă și la `/.well-known/openid-configuration`; aceasta include aceleași câmpuri ale serverului de autorizare, plus `subject_types_supported: ["public"]` și endpointul userinfo. Tokenurile ID și Documentele de metadate pentru ID-ul clientului (CIMD) nu sunt acceptate.

### Înregistrați un client public

Trimiteți JSON la `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"]
}
```

Salvați `client_id` returnat. Redirecționările trebuie să utilizeze HTTPS sau HTTP pe `127.0.0.1` ori `localhost`. Înregistrați URI-ul exact al callbackului, inclusiv portul și calea acestuia. Fragmentele și acreditările încorporate sunt respinse. Valorile opționale `client_uri` și `logo_uri` trebuie să utilizeze HTTPS; ThunderPhone nu le preia în timpul înregistrării. Înregistrarea este limitată ca rată. Clienții înregistrați nu expiră și rămân înregistrați atunci când o conexiune este revocată. Callbackurile HTTPS includ `https://chatgpt.com/connector/oauth/<id>` și `https://chatgpt.com/connector_platform_oauth_redirect`. Fiecare conexiune poate înregistra propriul client.

### Cod de autorizare

Deschideți endpointul de autorizare descoperit cu `client_id`, `redirect_uri` exact înregistrat, `response_type=code`, un `state` aleatoriu, `scope`, `code_challenge`, `code_challenge_method=S256` și `resource=https://api.thunderphone.com/v1/mcp`. Calculați provocarea ca rezumat SHA-256 base64url fără padding al unui verifier PKCE nou, cu entropie ridicată. Verificați `state` și `iss` returnate înainte de a schimba codul. Fiecare răspuns de autorizare, inclusiv refuzurile și erorile de protocol, identifică emitentul cu `iss`, care corespunde exact cu `issuer` descoperit. Erorile pentru un client sau callback nevalid sunt returnate local, fără redirecționare către acel callback.

Faceți schimbul la `POST /v1/oauth/token` utilizând codificarea de formular (este acceptat și 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
```

Parametrul opțional `resource` este acceptat atât în solicitările de autorizare, cât și în cele de tokenuri (inclusiv schimburile de reîmprospătare și pentru dispozitive). Când este omis, acesta are implicit resursa MCP descoperită. Când este prezent, trebuie să corespundă exact acelei resurse; alte valori returnează `invalid_target`. Tokenurile de acces includ acea audiență, iar MCP respinge tokenurile cu o audiență lipsă sau diferită cu `401` și o provocare de descoperire.

Solicitările de autorizare și codurile expiră după 10 minute. Fiecare răspuns pentru tokenuri conține `access_token`, `token_type` (`Bearer`), `expires_in` (3600 de secunde implicit), `refresh_token`, `scope`, `organization_id` și `organization_name`. Trimiteți tokenurile de acces numai prin antetul `Authorization: Bearer`. Nu introduceți niciodată tokenuri în URL-uri, jurnale, controlul versiunilor sau chat.

### Reîmprospătare și revocare

Reîmprospătați cu `grant_type=refresh_token`, `client_id`, `refresh_token` și `resource` la endpointul de tokenuri. Salvați atomic noul token de reîmprospătare și nu îl mai utilizați pe cel vechi. Tokenurile de reîmprospătare expiră după 30 de zile fără o reîmprospătare reușită. Un `scope` opțional poate restrânge permisiunile acordate. `offline_access` este întotdeauna inclus și tokenurile de reîmprospătare sunt întotdeauna emise. O solicitare inițială fără `scope` acordă doar `offline_access`, așadar clienții trebuie să solicite permisiunile de care au nevoie.

Reutilizarea codului și reutilizarea unui token de reîmprospătare rotit revocă întreaga autorizare. Serializați reîmprospătările în cadrul unui client; redarea unei acreditări schimbate cu succes nu este o strategie sigură de reîncercare.

Pentru deconectare, trimiteți `token` și `client_id` la `POST /v1/oauth/revoke`. Revocarea oricăruia dintre tokenuri îi revocă autorizarea, inclusiv toate tokenurile emise din acesta. Un token necunoscut returnează succes fără a dezvălui dacă există. Sesiunile Dashboard își pot lista propriile autorizări la `GET /v1/oauth/grants` și pot revoca una la `DELETE /v1/oauth/grants/<id>`, iar `X-ThunderPhone-Org` selectează organizația.

### Autorizare pentru dispozitive

Autorizarea pentru dispozitive este restricționată la clienții înregistrați în prealabil; clienții înregistrați dinamic primesc `unauthorized_client`. Clientul public preînregistrat `thunderphone-cli` acceptă autorizarea pentru dispozitive și reîmprospătarea. Trimiteți `client_id=thunderphone-cli` și `scope` la `POST /v1/oauth/device/code`. Afișați utilizatorului `user_code` și `verification_uri` sau deschideți `verification_uri_complete`.

Interogați endpointul de tokenuri cu `grant_type=urn:ietf:params:oauth:grant-type:device_code`, `client_id` și `device_code`, așteptând cel puțin `interval` returnat (5 secunde). Continuați la `authorization_pending`. La `slow_down`, utilizați noul `interval` returnat în răspuns (mărit cu 5 secunde) pentru fiecare solicitare ulterioară. Opriți-vă la `access_denied`, `expired_token` sau la orice altă eroare. Nu aprobați niciodată automat un cod de dispozitiv.

Clientul preînregistrat `thunderphone-mcp` acceptă `http://127.0.0.1/callback` și `http://localhost/callback` pe orice port. Schema, gazda, calea și interogarea trebuie să corespundă; schimbul de tokenuri trebuie să utilizeze URI-ul exact de redirecționare (inclusiv portul) din autorizare. Clienții înregistrați dinamic necesită potrivirea exactă a URI-ului de redirecționare, inclusiv portul. Înregistrați dinamic un callback diferit dacă aveți nevoie de altă cale.

### Verificări ale identității contului și ale domeniului spațiului de lucru

Solicitați atât `openid email`, cât și domeniile de aplicare pentru operațiunile de care are nevoie clientul dumneavoastră. Apelați `userinfo_endpoint` descoperit (`GET /v1/oauth/userinfo`) cu tokenul de acces în antetul Bearer. Un răspuns reușit conține:

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

`sub` este identificatorul stabil al utilizatorului; `org_id` este organizația selectată în timpul consimțământului. Endpointul necesită ambele domenii de aplicare pentru identitate și returnează `403` dacă lipsește oricare dintre ele. Returnează `403` cu `error=access_denied` dacă acel cont nu are un profil de e-mail verificat, în loc să afirme că un e-mail neverificat este de încredere. Tokenurile nevalide, expirate, revocate sau cu o audiență greșită returnează `401`. Tokenurile de sesiune umană și cheile API ale organizației nu pot apela userinfo. Nu este emis niciun token ID.

## Permisiuni disponibile

| Familie | Domenii |
| --- | --- |
| Agenți și importuri de agenți | `agents:read`, `agents:write` |
| Apeluri | `calls:read`, `calls:write` |
| Numere de telefon, apelanți blocați și VoIP | `numbers:read`, `numbers:write` |
| Cunoștințe | `knowledge:read`, `knowledge:write` |
| Campanii | `campaigns:read`, `campaigns:write` |
| Integrări, endpointuri webhook, servere MCP | `integrations:read`, `integrations:write` |
| Voci | `voices:read` |
| Scenarii de testare, rulări de testare, validare | `testing:read`, `testing:write` |
| Facturare | `billing:read` |
| Identitatea contului și e-mail verificat | `openid`, `email` (ambele sunt necesare pentru userinfo) |
| Conexiune persistentă | `offline_access` (inclus întotdeauna) |

GET, HEAD și OPTIONS utilizează domenii de citire; celelalte metode utilizează domenii de scriere. Modificările vocilor și ale facturării nu sunt disponibile prin OAuth; `POST /v1/voices/preview` utilizează `voices:read` deoarece previzualizează o voce fără a-i modifica configurația. Instrumentele MCP aplică domeniul operațiunii REST subiacente. Transferurile între organizații sunt refuzate chiar și atunci când utilizatorul care autorizează aparține ambelor organizații. Alte familii API, inclusiv gestionarea cheilor API și setările conturilor umane, nu sunt disponibile prin OAuth. O permisiune lipsă pentru o operațiune REST returnează `403` cu `WWW-Authenticate: Bearer error="insufficient_scope", scope="..."`. Tokenurile de acces nevalide sau expirate returnează `401`.


### Semnale de autentificare pentru instrumentele MCP

Fiecare instrument din `tools/list` include `securitySchemes: [{"type": "oauth2", "scopes": ["agents:read"]}]`, cu domeniul operațiunii REST a instrumentului respectiv. Instrumentele de documentație publică utilizează o listă goală de domenii și necesită în continuare o conexiune autentificată.

Un token valid căruia îi lipsește domeniul unui instrument primește HTTP `200` cu un `result` JSON-RPC care conține `isError: true`, text explicativ în `content` și `_meta["mcp/www_authenticate"]`. Acesta din urmă este o matrice care conține o provocare Bearer cu `resource_metadata`, `error="insufficient_scope"`, `error_description` și `scope` necesar. Instrumentul nu este executat. Utilizați această provocare pentru a solicita consimțământ extins. Autentificarea lipsă sau nevalidă continuă să returneze HTTP `401` cu `WWW-Authenticate`; eșecurile domeniilor REST continuă să returneze HTTP `403`.

## Păstrarea acreditărilor

API-ul execută `python manage.py oauth_cleanup` din oră în oră în staging și producție. Elimină cererile de autorizare și codurile de dispozitiv expirate. Tokenurile de acces expirate, codurile de autorizare și hashurile tokenurilor de reîmprospătare sunt eliminate doar după ce acordarea lor este revocată sau întreaga familie nu mai este validă. Hashurile utilizate sunt păstrate cât timp familia are un token de reîmprospătare, un cod de autorizare, un cod de dispozitiv aprobat sau un token de acces utilizabil, astfel încât curățarea să nu poată dezactiva detectarea reutilizării.
