משתמשים וסשנים ב‑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 הרגיל.
- זהו הקהל של הרשמה עצמית (דף register עם CAPTCHA) ושל התחברות ב‑OTP לפי מספר טלפון ב‑
username. שני הדפים נבנים בעורך הדפים.
הערות אבטחה
Section titled “הערות אבטחה”passwordלעולם אינו מוחזר בשאילתה, גם לא עם Master Key ו‑keys=passwordמפורש.- קריאה ל‑
_Userדורשת הזדהות. קריאה אנונימית נחסמת תמיד, אבל הקוד והסטטוס תלויים ב‑CLP של המערכת: בקונפיגורציה אחת404עם{"code":101,"error":"user needs to be authenticated"}, באחרת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
- סביבות וגישה — חבילות ומושבים
- שגיאות ופתרון תקלות · שרת ה‑MCP —
Create-or-Update-User, תפקידים והרשאות