---
title: "התחברות באמצעות OAuth"
description: "אשרו לקוחות MCP ואת ממשק שורת הפקודה של ThunderPhone בלי לשתף מפתח API."
---

OAuth מאפשר ליישום להתחבר לארגון ThunderPhone אחד עם ההרשאות שתאשרו. לקוחות ספרייה צריכים להשתמש ב-OAuth כברירת מחדל. מפתחות API של ארגון נשארים זמינים ללקוחות שדורשים אסימון Bearer המוגדר ידנית.

## אשרו חיבור

התחילו את החיבור בלקוח ה-MCP שלכם. התחברו ל-ThunderPhone, בדקו את שם היישום ואת ההרשאות המבוקשות, בחרו ארגון ובחרו **אישור**. בחרו **דחייה** אם לא התחלתם את החיבור או שאינכם סומכים על היישום. שמות יישומים מסופקים על ידי המפתחים שלהם ואינם תג אימות.

הרשאות קריאה חושפות את הנתונים שצוינו, כולל הקלטות ותמלילים כאשר מתבקשת ההרשאה `calls:read`. הרשאות כתיבה יכולות לשנות או למחוק משאבים; שיחות, קמפיינים, רכישות מספרי טלפון ופריסות עשויים לגרור עלויות או להשפיע על הייצור. תפקידכם בארגון עדיין חל.

לחיבור CLI, פתחו את קישור האימות המוצג במסוף שלכם, השוו את הקוד בן שמונת התווים, בחרו את הארגון שלכם ואשרו. פתיחת הקישור בלבד אינה מעניקה גישה. תוקף הקודים פג לאחר 15 דקות.

## נתקו יישום

פתחו בלוח הבקרה את **ארגון → מפתחות API → יישומים מורשים** ובחרו **ביטול הרשאה**. פעולה זו מבטלת את ההרשאה שבחרתם עבור הארגון הנוכחי, כולל אסימוני הגישה והרענון שלו. התחברו מחדש מהיישום אם ברצונכם לאשר אותו שוב.

## גילוי עבור לקוחות MCP

השתמשו בכתובת השרת `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**, אסימוני רענון מתחלפים, רישום דינמי ציבורי של לקוחות, ביטול והרשאת מכשיר. אין סודות לקוח או מענקי implicit. גילוי OpenID זמין גם ב-`/.well-known/openid-configuration`; הוא כולל את אותם שדות של שרת ההרשאה, בנוסף ל-`subject_types_supported: ["public"]` ולנקודת הקצה userinfo. אסימוני 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` עם `result` של JSON-RPC המכיל `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` מדי שעה בסביבות staging וייצור. הוא מסיר בקשות הרשאה וקודי מכשיר שפג תוקפם. אסימוני גישה שפג תוקפם, קודי הרשאה וגיבובי אסימוני רענון נגזמים רק לאחר שההענקה שלהם מבוטלת או שכל המשפחה אינה פעילה. גיבובים שנעשה בהם שימוש נשמרים כל עוד למשפחה יש אסימון רענון, קוד הרשאה, קוד מכשיר מאושר או אסימון גישה שניתן להשתמש בהם, כך שהניקוי אינו יכול להשבית זיהוי של הפעלה חוזרת.
