דילוג לתוכן
תיעוד Nodaro
תיעודמדריך הרכיביםמודליםתבניותסוכני AI (MCP)מפתחיםאירוח עצמימחקרהשוואות

אפליקציות OAuth

רישום אפליקציית OAuth, הפניית משתמשים למסך ההסכמה של Nodaro, החלפת הקוד באסימון גישה ל-90 ימים וקריאות ל-API בשם כל משתמש.

זמין ב-Nodaro Cloud · מהדורת Business

אפליקציית OAuth מאפשרת למוצר שלכם לקרוא ל-API של Nodaro בשם משתמשי Nodaro אחרים. כל משתמש מאשר את האפליקציה שלכם במסך הסכמה, השרת שלכם מחליף את הקוד שמתקבל באסימון גישה, וכל קריאה עם האסימון הזה פועלת בשם אותו משתמש, בגבולות ההרשאות שהוא אישר. Nodaro מממש את זרימת ה-authorization code הסטנדרטית של OAuth 2.0, עם PKCE ללקוחות שלא יכולים לשמור סוד.

יישומי מפתחים זמינים ב-Nodaro Cloud ובהתקנות של מהדורת Business.

OAuth או אסימון API אישי

מה אתם בוניםבמה להשתמשמבנה האסימון
סקריפט, משימת cron, משימת CI או צד שרת שמשתמש בחשבון שלכםאסימון API אישיndr_ ואחריו 64 תווים הקסדצימליים
מוצר מקוון שלמשתמשים שלו יש חשבונות Nodaro משלהםאפליקציית OAuthndr_app_ ואחריו 64 תווים הקסדצימליים

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

השתמשו ב-OAuth במקרים האלה:

  • אתם בונים מוצר מקוון, כמו אפליקציית ווב, SaaS או מרקטפלייס, ולמשתמשים שלכם יש חשבונות Nodaro משלהם.
  • כל משתמש נותן לאפליקציה שלכם רק חלק ממה שהחשבון שלו יכול לעשות.
  • כל משתמש יכול לנתק את האפליקציה שלכם בכל רגע, בלי להשפיע על אפליקציות אחרות.

איך הזרימה עובדת

  1. המשתמש לוחץ על חיבור ל-Nodaro באתר שלכם.
  2. האתר שלכם מפנה את הדפדפן לדף /oauth/authorize של Nodaro, עם ה-client_id, ה-redirect_uri, ה-scope וה-state שלכם.
  3. Nodaro מציג את מסך ההסכמה, אחרי התחברות אם צריך. המסך מציג את השם, הלוגו וההרשאות המבוקשות של האפליקציה שלכם, ואת החשבון שייתן את הגישה. הכפתור שימוש בחשבון אחר מנתק את המשתמש מהחשבון וחוזר לאותו מסך.
  4. המשתמש לוחץ על אישור, ו-Nodaro יוצר authorization code חד־פעמי.
  5. הדפדפן חוזר ל-redirect_uri שלכם עם ?code=...&state=....
  6. השרת שלכם מחליף את הקוד באסימון גישה ב-POST /v1/oauth/token, עם ה-client_id וה-client_secret שלכם.
  7. השרת שלכם קורא ל-API של Nodaro בשם המשתמש, עם Authorization: Bearer ndr_app_....

רישום האפליקציה שלכם

פתיחת הדף יישומי מפתחים

במופע של Nodaro שאליו אתם מכוונים, פתחו את הגדרות › יישומי מפתחים (/settings/developer-apps) ולחצו על יצירת יישום.

מילוי הטופס

הזינו את השם, את כתובות ההפניה ואת ההרשאות. השדות מתוארים בטבלה שלמטה.

שמירת סוד הלקוח

תיבת הדו־שיח היישום נוצר מציגה בשדה מזהה לקוח את מזהה הלקוח, שמתחיל ב-app_, ובשדה סוד לקוח את סוד הלקוח, שמתחיל ב-sec_. הסוד מוצג פעם אחת בלבד. העתיקו אותו למאגר הסודות שלכם לפני שאתם סוגרים את תיבת הדו־שיח: Nodaro שומר רק גיבוב שלו ולא יכול להציג אותו שוב.

שדהחובהכללים
שםכן1–100 תווים. מוצג במסך ההסכמה.
תיאורלאעד 500 תווים. מוצג מתחת לשם במסך ההסכמה.
כתובות הפניהכן1–10, אחת בכל שורה. כל אחת היא כתובת https://, או כתובת http://localhost לפיתוח. Nodaro משווה אותן בייט אחר בייט, ותווים כלליים לא נתמכים.
מקורות מורשיםלאעד 5 origins, כל אחד בלי נתיב, בלי מחרוזת שאילתה ובלי fragment. נדרשים רק אם הפרונטאנד שלכם קורא ל-Nodaro מדפדפן (CORS).
הרשאות מבוקשותכןלפחות אחת. זה המקסימום שהאפליקציה שלכם יכולה לבקש אי פעם: משתמשים יכולים לאשר פחות, והאפליקציה אף פעם לא יכולה לבקש יותר.
כתובת דף הבית, כתובת הלוגולאמגדירים אותן בדף של האפליקציה אחרי שיוצרים אותה. כל אחת היא כתובת https:// או http://localhost. לוגו מרובע נראה הכי טוב.

ניהול האפליקציה

  • החליפו את הסוד בדף של האפליקציה כשאתם מאבדים אותו, או כנוהל אבטחה שגרתי. הסוד הישן מפסיק לעבוד מיד, ולכן עדכנו מיד את התצורה של כל שירות שרץ.
  • מחקו את האפליקציה כדי לבטל כל אסימון גישה שניתן לה. משתמשים שאישרו אותה יצטרכו לחבר אותה שוב.
  • חמש אפליקציות לכל משתמש. לקוחות MCP שרשמו את עצמם מופיעים באותה רשימה, אבל לא נספרים במגבלה.
  • מקוד, המשאב client.developerApps של ה-SDK יוצר, מעדכן ומוחק אפליקציות ומחליף את הסודות שלהן. ראו את הדף SDK ל-TypeScript.

הרשאות

כל הרשאה (scope) היא היתר אחד שהאפליקציה שלכם מבקשת. בקשו רק את ההרשאות שאתם משתמשים בהן: המשתמשים רואים כל הרשאה מבוקשת במסך ההסכמה, ורשימה קצרה זוכה באמון שלהם.

הרשאהמה כתוב במסך ההסכמהמה היא מאפשרת
workflows:readקריאת התהליכים שלכםהצגת רשימה, קריאה וייצוא של תהליכים. הצגת רשימה וקריאה של האפליקציות שהמשתמש פרסם, עם נתוני השימוש והרווחים שלהן, וקריאת ברירות המחדל למונטיזציה.
workflows:writeיצירה ועריכה של תהליכיםיצירה, עדכון, מחיקה, ייבוא והעברה של תהליכים, ויצירת תת־תהליכים. פרסום, שינוי, מחיקה ושחזור של אפליקציות וסימון שלהן כמועדפות, וקביעת ברירות המחדל למונטיזציה.
workflows:executeהרצת תהליכים בשמכםהרצה של תהליכים, של אפליקציות שפורסמו ושל רכיבים שמורים שפורסמו, הרצת רכיבי יצירה בודדים דרך MCP, ושימוש באשף הפרומפטים. ניסיון חוזר של הרצות אפליקציה, רינדור הגרסה הסופית שלהן, שינוי השם שלהן, מחיקה ושחזור שלהן, וקריאה שלהן.
jobs:readקריאת מצב ותוצאות של משימותקריאת משימות, הסטטוס שלהן והתוצאות שלהן, קריאת סשני יצירה, קריאת הרצות אפליקציה, וניהול נקודות קצה של Webhook.
assets:readקריאת הנכסים שהעליתםקריאת הגלריה, ההעלאות, המועדפים, הרצות האפליקציה, הדמויות, המיקומים, האובייקטים והיצורים, והפלטות והמודבורדים של המשתמש.
assets:writeהוספה, שינוי ומחיקה של פריטים בספרייה שלכם: העלאות, דמויות, פוסטים שמורים, אוספים והערכות שמורות של צמתיםהעלאת מדיה, סימון משימות כמועדפות ודירוג שלהן, יצירה ועדכון של דמויות, מיקומים ואובייקטים, כתיבת פלטות ומודבורדים, כתיבת ערכות שמורות, התיקיות שלהן והמועדפים שלהן, ויצירה ותיוק של סשני יצירה.
credits:readצפייה ביתרת הקרדיטים שלכםקריאת יתרת הקרדיטים ותנועות הקרדיטים דרך MCP. אף נתיב REST לא בודק את ההרשאה הזאת.
apps:readקריאת יישומים שפורסמוהצגת רשימה של האפליקציות שהמשתמש פרסם ושל האפליקציות המועדפות עליו, וקריאת הקלטים של אפליקציות.
pipelines:readקריאת הפייפליינים שלכםקריאת פייפליינים של סיפור ← וידאו, הסטטוס שלהם והאישורים שממתינים בהם.
pipelines:executeהרצת פייפליינים בשמכם (עלול לצרוך קרדיטים)התחלת פייפליינים, הרצת השלבים שלהם והסתעפות משלב.
pipelines:approveאישור שלבי פייפליין בשמכםאישור הפלט של שלבים, ושימוש בצ׳אט של השלב ובכלי העזר לסצנות.
presets:readקריאת הערכות השמורות שלכםקריאת הערכות השמורות של המשתמש, תיקיות הערכות והערכות המועדפות. קטלוג הערכות המובנות ציבורי ולא דורש הרשאה. כתיבת ערכות דורשת assets:write.
workspaces:readצפייה בסביבות העבודה שאתם חברים בהןהצגת רשימה של סביבות העבודה של המשתמש.
workspaces:writeבחירת סביבת העבודה שבה הוא פועלבחירת סביבת העבודה שבה האפליקציה פועלת.
  • חלק מההרשאות שולטות בגישה לנתיבי REST, חלק בכלי ה-MCP, וחלק בשניהם. שרת ה-MCP מסתיר כל כלי שההרשאה שלו חסרה באסימון.
  • אסימון בלי ההרשאה שנתיב דורש נדחה עם 403 insufficient_scope, וההרשאה החסרה מופיעה ב-missingScope. ראו את הסעיף שגיאות.
  • הרשאות סביבת העבודה אף פעם לא מתווספות לאסימון שהונפק לפני שהיו ארגונים. כדי לתת אותן, המשתמש צריך לאשר שוב את האפליקציה שלכם.
  • הרצה של אפליקציה שפורסמה דורשת workflows:execute כדי להתחיל את ההרצה ו-jobs:read כדי לקרוא את ההתקדמות שלה. קריאת הרצות אפליקציה מתאפשרת גם עם assets:read או workflows:execute, ולכן אפליקציה שמתחילה הרצות תמיד יכולה לבדוק את הסטטוס שלהן.
  • טעינה של אפליקציה שפורסמה עם GET /v1/app/:slug לא דורשת הרשאה.
  • ההרשאות חלות רק על אסימונים של אפליקציות OAuth. Nodaro לא בודק הרשאות באסימוני סשן ובאסימוני API אישיים.

ניהול אפליקציות שפורסמו

עם אסימון של אפליקציית OAuth, נתיבי /v1/apps/* ונתיבי המונטיזציה האלה בודקים הרשאה:

הרשאהנתיבים
workflows:writePOST /v1/apps/publish, PATCH ו-DELETE /v1/apps/:appId, POST /v1/apps/:appId/restore, מתג המועדפים POST /v1/apps/favorite ו-PUT /v1/user/monetization-defaults.
workflows:read או apps:readGET /v1/apps/mine, GET /v1/apps/by-workflow/:workflowId, GET /v1/apps/favorites ו-GET /v1/apps/browse?favoritesOnly=true.
workflows:readGET /v1/apps/:appId/analytics (וגם /analytics/runs), GET /v1/apps/:appId/earnings, GET /v1/user/earnings ו-GET /v1/user/monetization-defaults.
workflows:executePOST /v1/app/:slug/run, POST /v1/app/:slug/runs, PATCH ו-DELETE /v1/app/:slug/runs/:runId, POST /v1/app/:slug/runs/:runId/resume, /render-final ו-/restore, DELETE /v1/app/:slug/runs/:runId/permanent ו-POST /v1/component/execute.
jobs:read, assets:read או workflows:executeGET /v1/app/:slug/runs, GET /v1/app/:slug/runs/:runId ו-GET /v1/me/archived-runs.

קטלוג השוק, GET /v1/apps/browse ו-GET /v1/apps/by-slug/:slug/latest-version, לא דורש הרשאה. אסימון בלי ההרשאה נדחה עם 403 insufficient_scope עם missingScope.

כשהמשתמש לוחץ על חיבור ל-Nodaro, הפנו את הדפדפן לכתובת הזאת:

https://nodaro.example.com/oauth/authorize?
  client_id=app_...&
  redirect_uri=https://yourapp.com/oauth/callback&
  response_type=code&
  scope=workflows:read+workflows:execute&
  state=<random CSRF token>
פרמטרכלל
client_idמזהה הלקוח של האפליקציה שלכם.
redirect_uriבדיוק אחת מכתובות ההפניה הרשומות שלכם, בייט אחר בייט. כתובת שלא תואמת נדחית עם 400 invalid_redirect_uri.
response_typeתמיד code. מסך ההסכמה דוחה כל ערך אחר.
scopeההרשאות שאתם מבקשים, מופרדות ברווחים או ב-+. הן חייבות להיות תת־קבוצה של ההרשאות המבוקשות של האפליקציה.
stateאסימון אקראי שאתם יוצרים לכל אישור גישה ושומרים בסשן של המשתמש. Nodaro מחזיר אותו בלי שינוי, ואתם חייבים לבדוק אותו.

צרו את state בשרת שלכם:

import { randomBytes } from "node:crypto"

// In your /connect handler:
const state = randomBytes(32).toString("hex")
req.session.oauthState = state

const url = new URL("https://nodaro.example.com/oauth/authorize")
url.searchParams.set("client_id", process.env.NODARO_CLIENT_ID!)
url.searchParams.set("redirect_uri", "https://yourapp.com/oauth/callback")
url.searchParams.set("response_type", "code")
url.searchParams.set("scope", "workflows:read workflows:execute")
url.searchParams.set("state", state)
res.redirect(url.toString())
  • אם המשתמש לוחץ על ביטול, Nodaro מפנה ל-redirect_uri שלכם עם error=access_denied, עם error_description ועם ה-state שלכם. התייחסו לביטול כאל תוצאה רגילה, לא כאל תקלה.
  • אם כתובת ההפניה לא רשומה, מסך ההסכמה מציג דף שגיאה ולא מפנה לשום מקום, גם בלחיצה על ביטול וגם בלחיצה על אישור.

החלפת הקוד באסימון

אחרי שהמשתמש לוחץ על אישור, Nodaro מפנה את הדפדפן לכתובת הקריאה החוזרת שלכם:

https://yourapp.com/oauth/callback?code=ndr_code_...&state=<your state>
  1. בדקו קודם את state. אם הוא לא תואם לערך שבסשן של המשתמש, עצרו: זו ההגנה מפני זיוף בקשות בין אתרים.
  2. החליפו את הקוד בשרת שלכם. לעולם אל תבצעו את הקריאה הזאת מדפדפן, שבו כל מי שיש לו כלי מפתחים יכול לקרוא את ה-client_secret שלכם.
import { createClient, StaticTokenAuth } from "@nodaro/sdk"

// The token endpoint is public: your client ID and secret authenticate
// the request, so the client needs no token of its own.
const client = createClient({
  baseUrl: "https://nodaro.example.com",
  auth: new StaticTokenAuth(""),
})

const tokens = await client.oauth.exchangeCode({
  client_id: process.env.NODARO_CLIENT_ID!,
  client_secret: process.env.NODARO_CLIENT_SECRET!,
  code: req.query.code as string,
  redirect_uri: "https://yourapp.com/oauth/callback",
})
// tokens.access_token: "ndr_app_..."
// tokens.scope:        the scopes the user granted, separated by spaces
// tokens.expires_in:   7776000 (seconds, that is 90 days)
// tokens.token_type:   "Bearer"
curl -X POST https://nodaro.example.com/v1/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "authorization_code",
    "client_id": "app_...",
    "client_secret": "sec_...",
    "code": "ndr_code_...",
    "redirect_uri": "https://yourapp.com/oauth/callback"
  }'

התגובה משתמשת בשמות השדות הסטנדרטיים של OAuth:

{
  "access_token": "ndr_app_...",
  "token_type": "Bearer",
  "scope": "workflows:read workflows:execute",
  "expires_in": 7776000
}
  • קוד עובד פעם אחת. החלפה שנייה של אותו קוד נדחית עם 400 invalid_grant.
  • תוקף הקוד פג 10 דקות אחרי שהוא הונפק. החליפו אותו ברגע שהוא מגיע לכתובת הקריאה החוזרת שלכם.
  • נקודת הקצה של האסימונים מקבלת גוף בקשה ב-JSON ובקידוד של טופס. לקוחות OAuth סטנדרטיים ששולחים application/x-www-form-urlencoded עובדים בלי שינוי, בשיטה client_secret_post.

לקוחות ציבוריים: PKCE

אפליקציות מובייל, אפליקציות של דף יחיד וכלי CLI לא יכולים לשמור client_secret. במקום זה הם משתמשים ב-PKCE. Nodaro תומך רק בשיטה S256; השיטה plain נדחית עם 400 invalid_request.

יצירת verifier ו-challenge

לפני ההפניה, צרו code_verifier אקראי עם אנטרופיה גבוהה. גזרו ממנו את code_challenge: קידוד base64url של גיבוב SHA-256 של ה-verifier.

שליחת ה-challenge עם בקשת ההרשאה

הוסיפו את code_challenge ואת code_challenge_method=S256 לכתובת ההרשאה:

https://nodaro.example.com/oauth/authorize?
  client_id=app_...&
  redirect_uri=https://yourapp.com/oauth/callback&
  response_type=code&
  scope=workflows:read+workflows:execute&
  state=<random CSRF token>&
  code_challenge=<base64url SHA-256 of the verifier>&
  code_challenge_method=S256

שליחת ה-verifier עם החלפת הקוד באסימון

שלחו code_verifier במקום client_secret:

curl -X POST https://nodaro.example.com/v1/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "authorization_code",
    "client_id": "app_...",
    "code": "ndr_code_...",
    "redirect_uri": "https://yourapp.com/oauth/callback",
    "code_verifier": "<the original verifier>"
  }'

לקוח שיכול לשמור סוד רשאי לשלוח גם סוד וגם verifier של PKCE. Nodaro בודק כל אחד מהם שנשלח.

קריאה ל-API עם האסימון

צרו לקוח אחד לכל משתמש, עם אסימון הגישה של אותו משתמש:

import { createClient, StaticTokenAuth } from "@nodaro/sdk"

const userClient = createClient({
  baseUrl: "https://nodaro.example.com",
  auth: new StaticTokenAuth(tokens.access_token),
})

// Every call acts as the user who authorized your app, within the granted scopes.
const projects = await userClient.projects.list()
const workflows = await userClient.workflows.list(projects.data[0].id)
const run = await userClient.workflows.run(workflows.data[0].id)

בלי ה-SDK, שלחו את האסימון בכותרת Authorization: Bearer של כל קריאת REST. נקודות הקצה מפורטות במדריך של ה-REST API.

כשתוקף האסימון פג

אסימון גישה תקף 90 ימים. Nodaro לא מנפיק אסימוני רענון: יש סוג אסימון אחד, מקום אחד לשמור אותו וכלל תפוגה אחד, במחיר של מסך הסכמה כל 90 ימים.

  • אחרי שתוקף האסימון פג או שהוא בוטל, קריאות ל-API נדחות עם 401. הפנו את המשתמש שוב ל-/oauth/authorize.
  • כשהמשתמש מאשר שוב את האפליקציה שלכם, Nodaro מעדכן את אישור הגישה שלו ומנפיק אסימון חדש. אסימונים קודמים נשארים בתוקף עד שהם פגים או מבוטלים, ולכן שמרו רישום של האסימונים שנמצאים בשימוש.
  • כדי להוסיף הרשאה, שלחו את המשתמש דרך כתובת ההרשאה עם scope רחב יותר. אישור הגישה הקיים מורחב.

שמירה בטוחה של אסימונים

  • שמרו את האסימונים בשרת שלכם. לעולם אל תשימו אסימון גישה ב-localStorage, ב-sessionStorage או בעוגייה ש-JavaScript יכול לקרוא.
  • הצפינו את האסימונים באחסון אם הפלטפורמה שלכם תומכת בזה. Nodaro שומר רק גיבוב SHA-256 של כל אסימון, ולכן אסימון יכול לדלוף רק אם מסד הנתונים שלכם דולף.
  • לעולם אל תשתפו אסימון בין משתמשים. כל אסימון שייך למשתמש Nodaro אחד; שימוש בו בהקשר של משתמש אחר הוא באג הרשאות.

ביטול אסימון

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

await client.oauth.revoke(tokens.access_token)
// { success: true }
curl -X POST https://nodaro.example.com/v1/oauth/revoke \
  -H "Content-Type: application/json" \
  -d '{ "token": "ndr_app_..." }'

נקודת הקצה של הביטול תמיד מחזירה 200, גם לאסימון שלא קיים, כך שאף אחד לא יכול להשתמש בה כדי לבדוק אם אסימון שניחש תקף. אחרי ביטול, קריאות עם האסימון נדחות עם 401.

כשהמשתמש מבטל את הגישה

משתמשים יכולים גם לסיים בעצמם את הגישה של האפליקציה שלכם. בדף הגדרות › אפליקציות מחוברות (/settings/connected-apps) מופיעים כל האפליקציות ועוזרי ה-AI שיש להם גישה לחשבון של המשתמש. כל פריט מציג את השם והסוג שלו, מתי הוא חובר, מתי השתמשו בו לאחרונה ואת ההרשאות שיש לו. הכפתור ביטול גישה מבקש אישור, ואז מסיים מיד את אישור הגישה ואת כל האסימונים שהונפקו במסגרתו.

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

רק סשן מחובר בדפדפן יכול להציג את אישורי הגישה האלה או לבטל אותם. הנתיבים GET /v1/me/connected-apps ו-POST /v1/me/connected-apps/:id/revoke דוחים אסימון גישה של OAuth ואסימון API אישי עם 401, ולכן אפליקציה לא יכולה לקרוא את הרשימה וגם לא לשנות אותה. כדי לסיים מקוד את הגישה של האפליקציה שלכם, השתמשו בנקודת הקצה של הביטול שלמעלה.

אפליקציית דפדפן שבנויה על ה-SDK קוראת את אישורי הגישה האלה ומבטלת אותם עם client.connectedApps() ועם client.revokeConnectedApp(authorizationId), בעזרת הסשן של המשתמש עצמו (supabaseAuth). עם מפתח API או עם אסימון של אפליקציה, שתי המתודות נכשלות עם 401, ולכן לא ה-CLI ולא שרת ה-MCP מציעים אותן.

שגיאות

נקודת הקצה של האסימונים עונה בשגיאות OAuth סטנדרטיות:

סטטוסשגיאהמתימה לעשות
400invalid_requestגוף הבקשה פגום או ששדה חסר.תקנו את הבקשה.
401invalid_client, "Unknown client" (לקוח לא מוכר)ה-client_id לא תואם לאף אפליקציה רשומה.בדקו את מזהה הלקוח בתצורה שלכם.
401invalid_client, "Bad client_secret" (סוד הלקוח שגוי)הסוד שגוי, לעיתים קרובות סוד ישן אחרי החלפה.טענו את הסוד הנוכחי והפעילו מחדש את השירות שלכם.
400invalid_grantעברו יותר מ-10 דקות מאז שהקוד הונפק, כבר נעשה בו שימוש או שה-redirect_uri שונה מזה שבבקשת ההרשאה.שלחו את המשתמש שוב דרך מסך ההסכמה, עם כתובות זהות.

שלב ההרשאה מציג את השגיאות האלה במסך ההסכמה עצמו, ואף פעם לא מפנה איתן:

סטטוסקודמתימה לעשות
400invalid_redirect_uriה-redirect_uri לא רשום לאפליקציה.הוסיפו את הכתובת בדף של האפליקציה.
400invalid_scopeאחת מההרשאות שהתבקשו לא נמצאת בהרשאות המבוקשות של האפליקציה.הוסיפו קודם את ההרשאה לאפליקציה.
404invalid_clientה-client_id לא מוכר, או שהאפליקציה מושעית.בדקו את מזהה הלקוח ואת הסטטוס של האפליקציה.

קריאות ל-API עם אסימון הגישה יכולות להיכשל בשגיאות האלה:

סטטוסקודמתימה לעשות
401unauthorizedתוקף האסימון פג, הוא בוטל או שהוא פגום.שלחו את המשתמש שוב דרך מסך ההסכמה.
403insufficient_scopeחסרה לאסימון ההרשאה שהנתיב דורש. גוף התגובה מציין אותה ב-missingScope.שלחו את המשתמש דרך מסך ההסכמה עם ההרשאה הרחבה יותר.

ה-SDK זורק את מקרה ה-403 כ-ForbiddenError עם missingScope בעל טיפוס, כך שתוכלו להציע הסכמה מחדש בלחיצה אחת:

import { ForbiddenError } from "@nodaro/sdk"

try {
  await userClient.workflows.run(workflowId)
} catch (err) {
  if (err instanceof ForbiddenError && err.missingScope) {
    // Send the user back to /oauth/authorize with the broader scope list.
    redirectToConsent({ scopes: [...currentScopes, err.missingScope] })
    return
  }
  throw err
}

רשימת בדיקות אבטחה

  • HTTPS בכל מקום. מופע ה-Nodaro, האפליקציה שלכם וכל כתובת הפניה משתמשים ב-https://. הכתובת http://localhost מיועדת רק לפיתוח מקומי.
  • בדקו את state בכל קריאה חוזרת. צרו אותו לכל אישור גישה ושמרו אותו בסשן של המשתמש.
  • שמרו את client_secret בשרת שלכם. לעולם אל תכללו אותו באפליקציית דפדפן, אל תרשמו אותו ביומן ואל תציגו אותו בהודעת שגיאה.
  • החליפו את הסוד לפחות פעם בשנה, ומיד אם אתם חושדים בדליפה.
  • רשמו רק כתובות הפניה שלכם. רשמו רק את הכתובות שאתם באמת משתמשים בהן.
  • בקשו את מספר ההרשאות הקטן ביותר. הוסיפו הרשאה כשאתם בונים את היכולת שצריכה אותה.
  • בטלו את האסימון בהתנתקות. קראו לנקודת הקצה של הביטול כשמשתמש מתנתק מהאפליקציה שלכם, כדי שאי אפשר יהיה להשתמש שוב באסימון שלו.
  • טפלו ב-missingScope. הציעו למשתמש הסכמה מחדש, ולא דף כללי של ״אין הרשאה״.

בדיקת הזרימה מקומית

לולאת הבדיקה המהירה ביותר דורשת מופע Nodaro עם יישומי מפתחים, כמו Nodaro Cloud או התקנה של מהדורת Business, ושרת קטן במחשב שלכם שמקבל את הקריאה החוזרת.

רישום אפליקציית בדיקה

צרו אפליקציה עם כתובת ההפניה http://localhost:8080/cb ועם ההרשאות workflows:read, workflows:execute ו-jobs:read.

הרצת שרת לקריאה החוזרת בפורט 8080

import express from "express"
import { createClient, StaticTokenAuth } from "@nodaro/sdk"

const NODARO_URL = "https://app.nodaro.ai" // or your Business edition install

const app = express()

app.get("/cb", async (req, res) => {
  const client = createClient({ baseUrl: NODARO_URL, auth: new StaticTokenAuth("") })
  const tokens = await client.oauth.exchangeCode({
    client_id: process.env.NODARO_CLIENT_ID!,
    client_secret: process.env.NODARO_CLIENT_SECRET!,
    code: req.query.code as string,
    redirect_uri: "http://localhost:8080/cb",
  })
  res.json(tokens)
})

app.listen(8080)

פתיחת כתובת ההרשאה ולחיצה על אישור

פתחו במופע את /oauth/authorize?client_id=app_...&redirect_uri=http://localhost:8080/cb&response_type=code&scope=workflows:read+workflows:execute&state=test123. אחרי שתלחצו על אישור, שרת הקריאה החוזרת יציג את ה-JSON של האסימון.

קריאה לנתיב אמיתי

השתמשו באסימון בנתיב כמו GET /v1/projects/<id>/workflows, ובדקו שהוא מחזיר 200 עם נתונים.

גילוי ורישום דינמי ללקוחות MCP

לקוחות MCP, כמו Claude, ChatGPT ו-Cursor, מוצאים בעצמם את נקודות הקצה של OAuth ויכולים לרשום את עצמם בזמן ריצה, בלי שמישהו ייכנס לדף יישומי מפתחים. את הצד של המשתמש מתאר הדף חיבור לקוח.

מסמכי גילוי

נקודת קצהתקןמטרה
GET /.well-known/oauth-authorization-serverRFC 8414איפה מאשרים, מקבלים אסימונים, נרשמים ומבטלים.
GET /.well-known/oauth-protected-resourceRFC 9728קושר את משאב ה-MCP, https://mcp.nodaro.ai/mcp, לשרת ההרשאות שלו.

כל מסמך זמין גם עם הסיומת /mcp, כי חלק מהלקוחות המחמירים מנסים את הצורה הזאת קודם. כל ארבעת המסמכים זמינים גם במארח של Nodaro וגם במארח של ה-MCP. המנפיק הוא ה-PUBLIC_URL של המופע, https://app.nodaro.ai ב-Nodaro Cloud.

במטא־דאטה של שרת ההרשאות מופיעים:

  • נקודות הקצה של ההרשאה, של האסימונים, של הרישום ושל הביטול;
  • סוג התגובה code וסוג ה-grant authorization_code;
  • PKCE בשיטה S256 בלבד;
  • שיטת האימות client_secret_post בנקודת הקצה של האסימונים;
  • כל ההרשאות, ב-scopes_supported.

רישום לקוחות דינמי

לקוח רושם את עצמו עם POST /v1/oauth/register (RFC 7591) ומקבל client_id שמתחיל ב-ndr_dcr_, ובנוסף client_secret. נקודת הקצה מקבלת עד 10 בקשות לדקה מכל כתובת IP. מנהל השרת של המופע מגדיר את MCP_DYNAMIC_REGISTRATION:

מצבהתנהגות
allowlist (ברירת המחדל)רק לקוחות ששמם מופיע ב-MCP_DCR_ALLOWLIST יכולים להירשם. האחרים נדחים עם 403 client_not_allowed.
openכל לקוח יכול להירשם, עד 5 רישומים שלא נעשה בהם שימוש לכל צמד של שם לקוח וכתובות הפניה בתוך 24 שעות (429 too_many_open_registrations).
offהרישום מושבת (403 dcr_disabled). במקום זה, מנהל השרת מחלק מזהה לקוח וסוד קבועים.

לקוח שרשם את עצמו בחר את השם שלו בעצמו, ולכן מסך ההסכמה מזהיר את המשתמש ש-Nodaro לא אימת אותו. ההרשאות שהלקוח מצהיר עליהן הן לידיעה בלבד: ההסכמה של המשתמש היא המחסום האמיתי, והלקוח יכול לבקש כל הרשאה תקפה. את ההגדרות של מנהל השרת מתאר הדף MCP בהתקנה באירוח עצמי.

התוסף ל-Figma בהתקנה באירוח עצמי

התוסף של Nodaro ל-Figma רץ בתוך Figma ולא יכול לקבל הפניה. במקום זה הוא מתחבר בלחיצת יד בסגנון device flow: התוסף מציג למשתמש קוד קצר, המשתמש מאשר את התוסף במסך ההסכמה הרגיל ומקליד את הקוד הזה, ואז התוסף מקבל את האסימון שלו. האסימון הוא אסימון רגיל של יישום מפתחים, עם ההרשאות jobs:read, assets:read, assets:write ו-credits:read, ואפשר לבטל אותו כמו כל אסימון אחר.

כדי לאפשר לתוסף להתחבר להתקנה שלכם:

  1. רשמו יישום מפתחים, בדף יישומי מפתחים או עם POST /v1/developer-apps. הוסיפו את <PUBLIC_URL>/v1/oauth/plugin/callback לכתובות ההפניה שלו, ובקשו את ארבע ההרשאות שלמעלה.
  2. שימו את מזהה הלקוח של האפליקציה ב-FIGMA_PLUGIN_OAUTH_CLIENT_ID בשרת.

בלי ההגדרה הזאת, כל נתיב חיבור של התוסף מחזיר 503 plugin_connect_not_configured. אם חסרה לאפליקציה כתובת הקריאה החוזרת או הרשאה, הנתיבים מחזירים 503 plugin_connect_misconfigured, ויומן השרת מציין מה חסר.

שאלות נפוצות

מתי צריך OAuth במקום אסימון API אישי?

השתמשו ב-OAuth כשהמוצר שלכם פועל בחשבונות Nodaro של אנשים אחרים, וכל משתמש צריך לאשר את האפליקציה שלכם ולהיות מסוגל לנתק אותה. לסקריפטים ולשרתים שמשתמשים רק בחשבון שלכם, אסימון API אישי פשוט יותר.

לכמה זמן תקף אסימון גישה של OAuth ב-Nodaro?

אסימון גישה של OAuth תקף 90 ימים. Nodaro לא מנפיק אסימוני רענון, ולכן כשתוקף האסימון פג או שהוא מבוטל, קריאות ל-API נדחות עם 401, ואתם שולחים את המשתמש שוב דרך מסך ההסכמה.

האם Nodaro תומך ב-PKCE?

כן, רק בשיטה S256. אפליקציות מובייל, אפליקציות של דף יחיד וכלי CLI שולחים code_challenge בבקשת ההרשאה ואת ה-code_verifier התואם בהחלפת הקוד באסימון, במקום סוד לקוח.

מה קורה אם איבדתי את סוד הלקוח?

Nodaro שומר רק גיבוב של הסוד ולא יכול להציג אותו שוב. החליפו את הסוד בדף של האפליקציה כדי לקבל סוד חדש. הסוד הישן מפסיק לעבוד מיד.

כמה יישומי מפתחים אפשר לרשום?

חמישה לכל משתמש. לקוחות MCP שרושמים את עצמם מופיעים באותה רשימה, אבל לא נספרים במגבלה.

האם משתמש יכול לבטל את הגישה שנתן לאפליקציה שלי?

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

עודכן לאחרונה

בדף הזה