דלגו לתוכן

או התחילו מנקודה בטוחה: אינדקס הכלים המלא · מפת הטבלאות המרכזיות

מערכת חדשה — 14 יום חינם

אימות והרשאות

עודכן 30.08.2026

לכל קריאה ל‑API יש בדיוק שתי שאלות: לאיזו מערכת אתם פונים, ובזכות מה מותר לכם. הראשונה נענית תמיד באותה כותרת; השנייה נענית בארבע דרכים שונות.

X-Parse-Application-Id: {appId}

ה‑Application Id מזהה את המערכת (ה“אפליקציה”) שלכם. הוא מזהה ציבורי, לא סוד: הוא מופיע ב‑JavaScript של כל דף נחיתה שמחובר למערכת, וזה בסדר גמור. השער האמיתי הוא ההרשאות בצד השרת, לא סודיות המזהה.

איפה מוציאים אותו: Databases ← המערכת שלכם ← לשונית Settings. ראו סביבות וגישה.

השיטה הכותרת מה היא מרשה איפה מותר להחזיק אותה
Application Id בלבד X-Parse-Application-Id getlead / web2table — ובנוסף, בפועל, גם POST /parse/files/… (ראו למטה) מותר בדפדפן
API Key X-Parse-API-Key הכול, בזהות Master; ניתן לביטול נקודתי צד שרת בלבד; אסור בדפדפן
Master Key X-Parse-Master-Key הכול, עוקף כל הרשאה; אין ביטול נקודתי צד שרת בלבד; אסור בדפדפן
Session Token X-Parse-Session-Token מה שהמשתמש עצמו מורשה צד שרת, או אפליקציה שהמשתמש התחבר אליה

ארבע שאלות, בסדר הזה:

  1. הקוד רץ בדפדפן של גולש אנונימי?Application Id בלבד, ורק מול getlead / web2table. עצרו כאן.
  2. ההרשאות צריכות להיות של משתמש מסוים (פורטל, אפליקציה שכל אחד רואה את שלו)? → Session Token דרך POST /parse/login.
  3. נדרשת פעולה שדורשת Master Key — כתיבה ל‑_Timeline, מחיקת קובץ, דגלי skipTriggers / skipTimeline ב‑Create-Many? → Master Key, ממנהל סודות, בצד שרת בלבד.
  4. אחרת → API Key. זו ברירת המחדל לשירותי צד שרת, כי אפשר לבטל אותה נקודתית.

1 · Application Id בלבד — הדלת הציבורית

Section titled “1 · Application Id בלבד — הדלת הציבורית”

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

JavaScript
await fetch(`https://api.mbapps.co.il/functions/${APP_ID}/getlead`, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-Parse-Application-Id': APP_ID },
body: JSON.stringify({ PhoneNumber: '0501234567', Email: 'a@b.co.il' }),
});

כתיבה לטבלה סגורה בפני קריאה אנונימית: POST /parse/classes/<Table> עם ה‑Application Id בלבד מוחזר עם {"code":119,"error":"This action is not allowed without a valid CAPTCHA"}גם אחרי שפתחתם את הרשאות הטבלה ל‑create: {"*": true} (אומת). שער ה‑CAPTCHA יושב לפני בדיקת ההרשאות, ולכן פתיחת ההרשאות לא קונה כלום מלבד חשיפה — הקריאה האנונימית כן נפתחת, והכתיבה עדיין נכשלת.

2 · API Key — לשירותים בצד שרת

Section titled “2 · API Key — לשירותים בצד שרת”

הפקה: תפריט המשתמשסביבת פיתוחDatabases ← המערכת שלכם ← Settings ← בלוק API Keys+ Add Key ← שם ← Save.

Bash
curl -sS "https://api.mbapps.co.il/parse/classes/Sales?limit=5" \
-H "X-Parse-Application-Id: {appId}" \
-H "X-Parse-API-Key: {apiKey}"
JavaScript
const APP_ID = "{appId}";
const API_KEY = "{apiKey}";
const res = await fetch("https://api.mbapps.co.il/parse/classes/Sales?limit=5", {
headers: {
"X-Parse-Application-Id": APP_ID,
"X-Parse-API-Key": API_KEY,
},
});
const data = await res.json();
Python
import requests
APP_ID = "{appId}"
API_KEY = "{apiKey}"
res = requests.get(
"https://api.mbapps.co.il/parse/classes/Sales",
headers={
"X-Parse-Application-Id": APP_ID,
"X-Parse-API-Key": API_KEY,
},
params={"limit": 5},
)
data = res.json()
PHP
$appId = "{appId}";
$apiKey = "{apiKey}";
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => "https://api.mbapps.co.il/parse/classes/Sales?limit=5",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"X-Parse-Application-Id: $appId",
"X-Parse-API-Key: $apiKey",
],
]);
$response = curl_exec($ch);
curl_close($ch);

שלוש עובדות שכדאי לדעת מראש:

  1. המפתח לא מוגבל בהיקף. הוא קורא וכותב בכל טבלה — כולל _User, _Timeline ו‑Config — והכתיבות שלו מתועדות בזהות Master. ההבדל היחיד מ‑Master Key הוא שאפשר לבטל אותו לבד (Revoke) בלי לגעת בשאר.
  2. הוא תקף רק תחת שם הכותרת שלו. אותו ערך בכותרת X-Parse-Master-Key נחשב לפרטי גישה שגויים ומוחזר ב‑{"code":119,"error":"Permission denied for action find on class …"}.
  3. שדה ה‑Name נשמר — תנו למפתח שם משמעותי כבר בהפקה. זה מה שיאפשר Revoke נקודתי בעוד חצי שנה.

3 · Session Token — הרשאות של משתמש אמיתי

Section titled “3 · Session Token — הרשאות של משתמש אמיתי”

כשצריך גבול הרשאות אמיתי (פורטל לקוחות, אפליקציה פנימית שבה כל משתמש רואה את שלו), מתחברים בשם המשתמש:

Bash
curl -sS -X POST "https://api.mbapps.co.il/parse/login" \
-H "X-Parse-Application-Id: {appId}" \
-H "Content-Type: application/json" \
-d '{ "username": "user@company.co.il", "password": "********" }'
JavaScript
const APP_ID = "{appId}";
const res = await fetch("https://api.mbapps.co.il/parse/login", {
method: "POST",
headers: {
"X-Parse-Application-Id": APP_ID,
"Content-Type": "application/json",
},
body: JSON.stringify({
username: "user@company.co.il",
password: "********",
}),
});
const data = await res.json();
Python
import requests
APP_ID = "{appId}"
res = requests.post(
"https://api.mbapps.co.il/parse/login",
headers={
"X-Parse-Application-Id": APP_ID,
"Content-Type": "application/json",
},
json={
"username": "user@company.co.il",
"password": "********",
},
)
data = res.json()
PHP
$appId = "{appId}";
$payload = json_encode([
"username" => "user@company.co.il",
"password" => "********",
]);
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => "https://api.mbapps.co.il/parse/login",
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"X-Parse-Application-Id: $appId",
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => $payload,
]);
$response = curl_exec($ch);
curl_close($ch);
JSON
{
"objectId": "g7y9tkhB7O",
"username": "user@company.co.il",
"email": "user@company.co.il",
"name": "ישראל ישראלי",
"createdAt": "2022-01-01T12:23:45.678Z",
"updatedAt": "2022-01-01T12:23:45.678Z",
"_failed_login_count": 0,
"last_success_login": { "__type": "Date", "iso": "2026-08-23T09:01:59.000Z" },
"ACL": { "g7y9tkhB7O": { "read": true, "write": true } },
"sessionToken": "r:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}

(createdBy / updatedBy חוזרים גם הם; הטוקן הוא מחרוזת בת 34 תווים שמתחילה ב‑r:. שם משתמש או סיסמה שגויים מוחזרים ב‑HTTP 404 עם {"code":101,"error":"Invalid username/password."}.)

מכאן והלאה מוסיפים לכל קריאה:

X-Parse-Session-Token: r:xxxxxxxxxxxxxxxxxxxxxxxxx

הגישה מוגבלת לתפקידים של המשתמש ולהרשאות ברמת הטבלה. ניתוק: POST /parse/logout עם X-Parse-Application-Id + X-Parse-Session-Token.

מדיניות סיסמאות של המוצר: הסיסמה חייבת לעמוד ב‑ (?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,} — מינימום 8 תווים, אות קטנה, אות גדולה וספרה. הפרה מוחזרת ב‑{"code":142,"error":"Password does not meet the Password Policy requirements."}. ה‑username אמור להיות כתובת אימייל — זו מוסכמת מוצר שכל זרימות ההתחברות והשחזור מניחות, אבל השרת אינו אוכף אותה: username שאינו אימייל מתקבל.

4 · Master Key — גישה מלאה, עוקפת כל הרשאה

Section titled “4 · Master Key — גישה מלאה, עוקפת כל הרשאה”
HTTP
X-Parse-Application-Id: {appId}
X-Parse-Master-Key: {masterKey}

עוקף כל הרשאה ברמת הטבלה וברמת הרשומה. פעולות מסוימות דורשות אותו:

הפעולה למה
מחיקת קובץ (DELETE /parse/files/<name>) אנונימי מקבל unauthorized: master key is required
כתיבה ל‑_Timeline אפשרית עם Master Key בלבד — וזו מגבלת ביקורת, ראו יומנים
skipTriggers / skipTimeline בכלי Create-Many הדגלים מכובדים רק באימות Master Key
קריאת סכימות של _Role / _Session בשכבת ה‑MCP Get-Schema מחזיר עליהן {}

ומה שלא דורש Master Key, בניגוד למה שנהוג לחשוב: טבלת Config נקראת גם עם API Key וגם עם Session Token של משתמש מורשה (אנונימי ומשתמש בלי תפקיד מקבלים 119). היא הייתה חסומה בשכבת ה‑MCPError: Table is restricted — עד גרסת השרת של 25.08.2026; מאז ההגבלה הוסרה ו‑Get-Schema / Get-Data / Create-Data עליה עובדים גם משם (אומת שוב 28.08.2026, web-forms-07). גם האגרגציה ב‑REST — GET /parse/classes-aggregate/<Table> — עובדת עם API Key ועם Session Token של משתמש מורשה; אנונימי מקבל 119. (הנתיב הגנרי /parse/aggregate/ אינו קיים בפריסה — 404, ראו דוח הבאג core-api-01 ו‑אגרגציות.)

אותו מפתח, שכבה אחרת — MCP

Section titled “אותו מפתח, שכבה אחרת — MCP”

שכבת ה‑MCP אינה עולם נפרד מבחינת אימות: אותו API Key שנשלח ב‑REST נשלח שם, באותו שם כותרת בדיוק.

מצב מה הלקוח שולח הזהות בשרת מודל ההרשאות
Application Id + API Key X-Parse-Application-Id + X-Parse-API-Key משתמש הדמה Master ללא — עוקף כל הרשאת טבלה
התחברות משתמש (OAuth 2.1) Authorization: Bearer <token> משתמש ה‑CRM שנכנס התפקיד שלו בתוספת הרשאות ה‑MCP שלו; לעולם לא מעבר לתפקיד הבסיס

שלוש נקודות שמפתיעות מפתחים:

  1. המפתח תקף רק תחת שם הכותרת שלו — גם כאן. אותו ערך ב‑X-Parse-Master-Key = פרטי גישה שגויים.
  2. למשתמשים אין גישת MCP כברירת מחדל — גם לא ל‑owner. היא ניתנת פרטנית בלשונית MCP Permissions של כרטיס המשתמש (סביבת הפיתוח ← Databases ← המערכת ← Users ← המשתמש): ארבע תיבות — mcp:view, mcp:create, mcp:update, mcp:edit-page-and-schema — כולן כבויות במערכת חדשה. המסך עצמו מציין שההרשאות כפופות להרשאות הטבלה של המשתמש ושהשימוש ב‑MCP תלוי בתוכנית המנוי.
  3. חיבור אחד = מערכת אחת. ניתוב הפרטים קורה בהגדרת החיבור, לא בקריאה.
מה קרה מה תראו
כותרת אימות חסרה לגמרי (MCP) Authorization header is required
פרטי גישה שגויים (MCP) HTTP 200 ותשובת הכלי Permission denied for action find on class …
Session Token פג/לא תקין (REST) {"code":209,"error":"invalid session token"} — HTTP 400
שם משתמש או סיסמה שגויים ב‑POST /parse/login {"code":101,"error":"Invalid username/password."} — HTTP 404
API Key / Master Key מבוטל או שגוי (REST) {"code":119,"error":"Permission denied for action find on class …"} — זהה לקריאה בלי הרשאה
כתיבה אנונימית ל‑REST {"code":119,"error":"This action is not allowed without a valid CAPTCHA"}
קריאה בלי הרשאה (REST) {"code":119,"error":"Permission denied for action find on class Accounts."} — אותו קוד, הודעה אחרת
שם שדה לא חוקי {"code":105,"error":"Invalid field name: bl!ng."}
רשומה לא נמצאה — או שההרשאות מסתירות אותה {"code":101,"error":"Object not found."}
סיסמה שאינה עומדת במדיניות {"code":142,"error":"Password does not meet the Password Policy requirements."}
  • בדפדפן: רק Application Id, ורק מול getlead / web2table.
  • בשרת: API Key (מועדף: ניתן לביטול) או Master Key, מתוך מנהל סודות.
  • בשם משתמש: Session Token, כשההרשאות אמורות להיות של המשתמש ולא של המערכת.
  • לסוכני AI: ראו שרת ה‑MCP: שם יש גם מסלול OAuth 2.1 שקושר את החיבור למשתמש אמיתי.
  • בכל מקום: מפתח לכל צרכן, כדי שביטול יהיה נקודתי.