משתמשים וסשנים ב‑REST
שכבת המשתמשים היא Parse סטנדרטי, עם שלוש הרחבות מוצר מהותיות: username חייב להיות אימייל, מדיניות סיסמאות נאכפת בשרת, ויצירת משתמש ב‑REST אינה משייכת רישיון.
הנקודות
Section titled “הנקודות”| פעולה | נקודת קצה | מה נדרש |
|---|---|---|
| הרשמה | POST /parse/users |
Master Key או API Key + גוף {username, password, …} |
| התחברות | POST /parse/login |
X-Parse-Application-Id + גוף {username, password} |
| המשתמש הנוכחי | GET /parse/users/me |
X-Parse-Session-Token |
| עדכון | PUT /parse/users/{objectId} |
Master Key — ראו האזהרה בהמשך |
| איפוס סיסמה | POST /parse/requestPasswordReset |
גוף {"email": "…"} |
| התנתקות | POST /parse/logout |
X-Parse-Session-Token |
curl -sS -X POST "https://api.mbapps.co.il/parse/users" \ -H "X-Parse-Application-Id: $APP_ID" \ -H "X-Parse-API-Key: $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "username": "user@company.co.il", "password": "Sod1Hazak", "email": "user@company.co.il", "name": "ישראל ישראלי", "phone": "0501234567"}'const res = await fetch('https://api.mbapps.co.il/parse/users', { method: 'POST', headers: { 'X-Parse-Application-Id': APP_ID, 'X-Parse-API-Key': API_KEY, 'Content-Type': 'application/json', }, body: JSON.stringify({ username: 'user@company.co.il', password: 'Sod1Hazak', email: 'user@company.co.il', name: 'ישראל ישראלי', phone: '0501234567', }),});import requests
res = requests.post( "https://api.mbapps.co.il/parse/users", headers={ "X-Parse-Application-Id": APP_ID, "X-Parse-API-Key": API_KEY, }, json={ "username": "user@company.co.il", "password": "Sod1Hazak", "email": "user@company.co.il", "name": "ישראל ישראלי", "phone": "0501234567", }, timeout=30,)<?php$ch = curl_init('https://api.mbapps.co.il/parse/users');curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ 'X-Parse-Application-Id: ' . $appId, 'X-Parse-API-Key: ' . $apiKey, 'Content-Type: application/json', ], CURLOPT_POSTFIELDS => json_encode([ 'username' => 'user@company.co.il', 'password' => 'Sod1Hazak', 'email' => 'user@company.co.il', 'name' => 'ישראל ישראלי', 'phone' => '0501234567', ], JSON_UNESCAPED_UNICODE),]);$response = curl_exec($ch);curl_close($ch);201 Created →
{ "objectId": "g7y9tkhB7O", "createdAt": "2026-08-20T09:14:22.005Z", "sessionToken": "r:xxxxxxxxxxxxxxxxxxxxxxxxx"}ההרשמה מחזירה טוקן סשן מיידי — המשתמש כבר מחובר.
מדיניות הסיסמאות שהשרת אוכף
Section titled “מדיניות הסיסמאות שהשרת אוכף”מינימום 8 תווים, לפחות אות קטנה אחת, אות גדולה אחת וספרה אחת. כל הפרה — קצרה מדי, בלי אות גדולה, בלי ספרה — מוחזרת באותה שגיאה בדיוק:
{ "code": 142, "error": "Password does not meet the Password Policy requirements." }ההודעה אינה מפרטת מה חסר, אז אל תנסו לנתח אותה — ולידציה בצד הלקוח תחסוך למשתמש את הניחוש.
התחברות
Section titled “התחברות”curl -sS -X POST "https://api.mbapps.co.il/parse/login" \ -H "X-Parse-Application-Id: $APP_ID" \ -H "Content-Type: application/json" \ -d '{ "username": "user@company.co.il", "password": "********" }'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: '********' }),});import requests
res = requests.post( "https://api.mbapps.co.il/parse/login", headers={"X-Parse-Application-Id": APP_ID}, json={"username": "user@company.co.il", "password": "********"}, timeout=30,)<?php$ch = curl_init('https://api.mbapps.co.il/parse/login');curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ 'X-Parse-Application-Id: ' . $appId, 'Content-Type: application/json', ], CURLOPT_POSTFIELDS => json_encode([ 'username' => 'user@company.co.il', 'password' => '********', ], JSON_UNESCAPED_UNICODE),]);$response = curl_exec($ch);curl_close($ch);{ "username": "user@company.co.il", "objectId": "g7y9tkhB7O", "createdAt": "2022-01-01T12:23:45.678Z", "updatedAt": "2022-01-01T12:23:45.678Z", "sessionToken": "r:xxxxxxxxxxxxxxxxxxxxxxxxx"}התשובה בפועל עשירה יותר מהדוגמה — היא כוללת גם email, name, ACL, createdBy/updatedBy, ואחרי ההתחברות הראשונה גם last_success_login ו‑_failed_login_count. שם משתמש או סיסמה שגויים מוחזרים ב‑HTTP 404 עם {"code":101,"error":"Invalid username/password."}.
מכאן והלאה, כל קריאה נושאת:
והגישה מוגבלת לתפקידים של המשתמש ולהרשאות ברמת הטבלה. זו הדרך היחידה לקבל גבול הרשאות אמיתי — ראו אימות והרשאות.
המשתמש הנוכחי, וקוד 209
Section titled “המשתמש הנוכחי, וקוד 209”curl -sS "https://api.mbapps.co.il/parse/users/me" \ -H "X-Parse-Application-Id: $APP_ID" \ -H "X-Parse-Session-Token: r:xxxxxxxxxxxxxxxxxxxxxxxxx"const res = await fetch('https://api.mbapps.co.il/parse/users/me', { headers: { 'X-Parse-Application-Id': APP_ID, 'X-Parse-Session-Token': 'r:xxxxxxxxxxxxxxxxxxxxxxxxx', },});import requests
res = requests.get( "https://api.mbapps.co.il/parse/users/me", headers={ "X-Parse-Application-Id": APP_ID, "X-Parse-Session-Token": "r:xxxxxxxxxxxxxxxxxxxxxxxxx", }, timeout=30,)<?php$ch = curl_init('https://api.mbapps.co.il/parse/users/me');curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'X-Parse-Application-Id: ' . $appId, 'X-Parse-Session-Token: r:xxxxxxxxxxxxxxxxxxxxxxxxx', ],]);$response = curl_exec($ch);curl_close($ch);טוקן שפג או בוטל מוחזר כך (עם HTTP 400):
{ "code": 209, "error": "invalid session token" }async function callWithSession(path, init = {}) { let token = getStoredToken(); const send = () => fetch(`https://api.mbapps.co.il/parse${path}`, { ...init, headers: { ...init.headers, 'X-Parse-Application-Id': APP_ID, 'X-Parse-Session-Token': token }, });
let res = await send(); if (res.status === 400 || res.status === 401 || res.status === 403) { const body = await res.clone().json().catch(() => ({})); if (body.code === 209) { // הטוקן פג — התחברות מחדש וניסיון אחד נוסף token = await login(); storeToken(token); res = await send(); } } return res;}עדכון משתמש
Section titled “עדכון משתמש”curl -sS -X PUT "https://api.mbapps.co.il/parse/users/g7y9tkhB7O" \ -H "X-Parse-Application-Id: $APP_ID" \ -H "X-Parse-Master-Key: $MASTER_KEY" \ -H "Content-Type: application/json" \ -d '{ "phone": "0509999999", "job": "מנהל מכירות" }'const res = await fetch('https://api.mbapps.co.il/parse/users/g7y9tkhB7O', { method: 'PUT', headers: { 'X-Parse-Application-Id': APP_ID, 'X-Parse-Master-Key': MASTER_KEY, 'Content-Type': 'application/json', }, body: JSON.stringify({ phone: '0509999999', job: 'מנהל מכירות' }),});import requests
res = requests.put( "https://api.mbapps.co.il/parse/users/g7y9tkhB7O", headers={ "X-Parse-Application-Id": APP_ID, "X-Parse-Master-Key": MASTER_KEY, }, json={"phone": "0509999999", "job": "מנהל מכירות"}, timeout=30,)<?php$ch = curl_init('https://api.mbapps.co.il/parse/users/g7y9tkhB7O');curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_CUSTOMREQUEST => 'PUT', CURLOPT_HTTPHEADER => [ 'X-Parse-Application-Id: ' . $appId, 'X-Parse-Master-Key: ' . $masterKey, 'Content-Type: application/json', ], CURLOPT_POSTFIELDS => json_encode([ 'phone' => '0509999999', 'job' => 'מנהל מכירות', ], JSON_UNESCAPED_UNICODE),]);$response = curl_exec($ch);curl_close($ch);שדות _User שהמוצר מוסיף
Section titled “שדות _User שהמוצר מוסיף”במערכת חדשה קיימים בסכימה רק חלק מהם; השאר נוצרים ברגע שכותבים אליהם. אל תניחו קיום — שלפו סכימה.
| שדה | טיפוס | קיים בבסיס | לְמה |
|---|---|---|---|
name |
String | ✔ | שם תצוגה (עברית בסדר גמור) |
status |
Pointer→UserStatuses |
✔ | סטטוס נוכחות |
profile_image |
File | ✔ | תמונת פרופיל |
last_success_login |
Date | ✔ | התחברות מוצלחת אחרונה |
emailVerified |
Boolean | ✔ | |
language |
String | ✔ | שפת הממשק |
phone · extension |
String | ✘ | טלפון ושלוחה במרכזייה |
job |
String | ✘ | תפקיד — טקסט, לא הרשאה |
active |
Boolean | ✘ | מתג ההשבתה. false = חסום כניסה, גם ב‑REST: {"code":101,"error":"User is not active."} |
isPortalUser |
Boolean | ✘ | משתמש פורטל חיצוני — אינו צורך מושב רישוי |
בנוסף, אובייקט המשתמש שחוזר מ‑/parse/login נושא את _failed_login_count — מונה כשלונות ההתחברות עד להצלחה הזו; ברשומה עצמה המונה מתאפס ל‑0 מיד אחרי התחברות מוצלחת.
איפוס סיסמה
Section titled “איפוס סיסמה”curl -sS -X POST "https://api.mbapps.co.il/parse/requestPasswordReset" \ -H "X-Parse-Application-Id: $APP_ID" \ -H "Content-Type: application/json" \ -d '{ "email": "user@company.co.il" }'const res = await fetch('https://api.mbapps.co.il/parse/requestPasswordReset', { method: 'POST', headers: { 'X-Parse-Application-Id': APP_ID, 'Content-Type': 'application/json', }, body: JSON.stringify({ email: 'user@company.co.il' }),});import requests
res = requests.post( "https://api.mbapps.co.il/parse/requestPasswordReset", headers={"X-Parse-Application-Id": APP_ID}, json={"email": "user@company.co.il"}, timeout=30,)<?php$ch = curl_init('https://api.mbapps.co.il/parse/requestPasswordReset');curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ 'X-Parse-Application-Id: ' . $appId, 'Content-Type: application/json', ], CURLOPT_POSTFIELDS => json_encode([ 'email' => 'user@company.co.il', ]),]);$response = curl_exec($ch);curl_close($ch);שולח מייל איפוס למשתמש, ומחזיר {"message":"Your request will be processed shortly"}.
התשובה זהה גם לכתובת שאינה קיימת במערכת — כלומר הנקודה אינה מדליפה אילו כתובות רשומות.
איפוס יזום על ידי מנהל הוא פשוט עדכון עם password חדש (Master Key או שכבת המוצר).
התנתקות
Section titled “התנתקות”curl -sS -X POST "https://api.mbapps.co.il/parse/logout" \ -H "X-Parse-Application-Id: $APP_ID" \ -H "X-Parse-Session-Token: r:xxxxxxxxxxxxxxxxxxxxxxxxx"const res = await fetch('https://api.mbapps.co.il/parse/logout', { method: 'POST', headers: { 'X-Parse-Application-Id': APP_ID, 'X-Parse-Session-Token': 'r:xxxxxxxxxxxxxxxxxxxxxxxxx', },});import requests
res = requests.post( "https://api.mbapps.co.il/parse/logout", headers={ "X-Parse-Application-Id": APP_ID, "X-Parse-Session-Token": "r:xxxxxxxxxxxxxxxxxxxxxxxxx", }, timeout=30,)<?php$ch = curl_init('https://api.mbapps.co.il/parse/logout');curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ 'X-Parse-Application-Id: ' . $appId, 'X-Parse-Session-Token: r:xxxxxxxxxxxxxxxxxxxxxxxxx', ],]);$response = curl_exec($ch);curl_close($ch);מבטל את הסשן. כל שימוש נוסף באותו טוקן יחזיר 209.
שלוש ההחלטות שמרכיבות משתמש עובד
Section titled “שלוש ההחלטות שמרכיבות משתמש עובד”| # | ההחלטה | מה קורה בלעדיה |
|---|---|---|
| 1 | משתמש — שורה ב‑_User |
אין למי להתחבר |
| 2 | רישום בשכבת האפליקציה + חבילה / מושב — מה ש‑Create-or-Update-User והממשק עושים, ו‑POST /parse/users לא |
המשתמש נחסם במסך הכניסה ל‑CRM (“תקלה בשיוך לאפליקצייה”). POST /parse/login בכל זאת יחזיר לו טוקן |
| 3 | תפקיד — ודרכו הרשאות הטבלה (find / get / create / update / delete) | כל שאילתה מוחזרת ב‑119 Permission denied; בממשק זה נראה כמו טבלאות ריקות |
שלושתן בלתי תלויות, ואף אחת מהן אינה אוטומטית. הרשאות אפקטיביות = איחוד של כל התפקידים של המשתמש.
| הסימפטום | מה חסר |
|---|---|
| “המשתמש לא מצליח להתחבר” | רישום בשכבת האפליקציה / חבילה, active: false, או נעילה זמנית אחרי כשלונות התחברות |
| “המשתמש מחובר אבל לא רואה כלום” | תפקיד, או CLP של הטבלה |
| “המשתמש רואה רשומות של אחרים” | סינון ברמת שורה (הרשאות מתקדמות) |
משתמשי פורטל
Section titled “משתמשי פורטל”isPortalUser: true מסמן משתמש חיצוני — לקוח שרואה רק את החשבוניות שלו, תלמיד שרואה את הקורסים שלו.
- אינם צורכים מושב רישוי — פורטל לקוחות אינו מוגבל במספר משתמשים.
- מקבלים תפקיד ייעודי צר עם CLP מוגבל.
- אינם רואים את ממשק ה‑CRM הרגיל.
הערות אבטחה
Section titled “הערות אבטחה”passwordלעולם אינו מוחזר בשאילתה — גם לא עם Master Key ועםkeys=passwordמפורש.- קריאה ל‑
_Userדורשת הזדהות (authentication). קריאה אנונימית נחסמת תמיד, אבל הקוד והסטטוס המדויקים תלויים בהגדרות ה‑CLP של המערכת: בקונפיגורציה אחת מוחזר404עם{"code":101,"error":"user needs to be authenticated"}, ובקונפיגורציית CLP אחרת מוחזר400עם{"code":119,"error":"Permission denied for action find on class _User."}. אל תתלו לוגיקה בקוד שגיאה מסוים — בדקו שהקריאה נכשלה, לא איך. יצירה ומחיקה נעולות ל‑Master Key / API Key. - כשלונות התחברות נספרים (
_failed_login_count), ויש מנגנון נעילה זמנית: אחרי 8 כשלונות רצופים החשבון ננעל ל‑30 דקות, וכל ניסיון נוסף — גם עם הסיסמה הנכונה — מוחזר ב‑{"code":101,"error":"Your account is locked due to multiple failed login attempts. Please try again after 30 minute(s)"}. לולאת ניסיונות אוטומטית תנעל את החשבון; שימו לב שהודעת הנעילה שונה מהודעת הסיסמה השגויה, ומאפשרת לקוד להבחין בין השתיים. - ה‑API Key מגיע גם ל‑
_User. הוא אינו אישור מוגבל‑היקף — ראו אימות והרשאות.
המשך מכאן
Section titled “המשך מכאן”- אימות והרשאות — ארבע השיטות, כולל Session Token
- סביבות וגישה — חבילות, מושבים ולמה משתמש חדש תקוע
- שגיאות ופתרון תקלות — 209 ושאר הקודים
- שרת ה‑MCP —
Create-or-Update-Userוהכלים לתפקידים והרשאות