אימות

Cliqer מבצעת אימות באמצעות עוגיית סשן מסוג httpOnly (session_token), שנוצרת על ידי POST /api/auth/login. דפדפנים שולחים אותה אוטומטית בכל בקשה; כלים לתקשורת בין שרתים שומרים אותה במאגר עוגיות (cookie jar). צוותי Studio 8K ו-Enterprise יכולים בנוסף ליצור מפתחות API לגישה בין שרתים, שנשלחים בתור Authorization: Bearer cliqer_<key>, ראו אימות באמצעות מפתח API בהמשך.
מודל הסשן
| פרט הזדהות | היכן הוא נשמר | איך מקבלים אותו |
|---|---|---|
עוגיית סשן (session_token) | עוגייה מסוג httpOnly ו-Secure במארח Cliqer שלכם | נקבעת על ידי POST /api/auth/login, ומוחלפת אוטומטית על ידי השרת |
העוגייה היא HttpOnly, ולכן לא ניתן לקרוא אותה מ-JavaScript. משך החיים שלה תואם ל-TTL של הסשן בשרת, והיא מתחדשת באופן שקוף בכל פעם שקוראים ל-GET /api/auth/me. אין נקודת קצה נפרדת לרענון שצריך לקרוא לה; כדי לשמור על לקוח שפועל לאורך זמן במצב תקין, יש לקרוא ל-GET /api/auth/me מעת לעת.
מחזור החיים של הסשן
שימוש בסשן
דפדפנים מצרפים את העוגייה אוטומטית. בלקוחות שפועלים בין שרתים, יש לשמור את העוגייה שתגובת ההתחברות קובעת ולשלוח אותה בבקשות הבאות:
# Save the session cookie on login, then reuse it
curl -X POST "$BASE_URL/api/auth/login" \
-H "Content-Type: application/json" \
-c cookies.txt \
-d '{"email":"user@example.com","password":"your_password"}'
curl -X GET "$BASE_URL/api/auth/me" -b cookies.txt
// Same-origin $fetch sends the httpOnly cookie automatically.
// Cross-origin fetch must opt in with credentials: 'include'.
const me = await $fetch('/api/auth/me')
import requests
session = requests.Session() # persists the session cookie
session.post('$BASE_URL/api/auth/login',
json={'email': 'user@example.com', 'password': 'your_password'})
me = session.get('$BASE_URL/api/auth/me').json()
jar, _ := cookiejar.New(nil)
client := &http.Client{Jar: jar}
// Login stores the session cookie in the jar; later requests reuse it.
client.Post("$BASE_URL/api/auth/login", "application/json", body)
resp, _ := client.Get("$BASE_URL/api/auth/me")
$ch = curl_init('$BASE_URL/api/auth/login');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'email' => 'user@example.com', 'password' => 'your_password'
]));
curl_exec($ch);
// reqwest with cookie_store persists the session cookie across calls
let client = reqwest::Client::builder()
.cookie_store(true)
.build()?;
client.post("$BASE_URL/api/auth/login")
.json(&serde_json::json!({"email": "user@example.com", "password": "your_password"}))
.send().await?;
let me = client.get("$BASE_URL/api/auth/me").send().await?;
אימות באמצעות מפתח API
צוותי Studio 8K ו-Enterprise יכולים ליצור מפתחות API ארוכי טווח לגישה בין שרתים, כחלופה להחזקת פרטי ההתחברות של משתמש. אפשר ליצור ולבטל אותם בלוח הבקרה תחת צוות → מפתחות API (/dash/team/api-keys); יצירת מפתח שמורה לבעלי הצוות (או לתפקיד מותאם אישית שקיבל את ההרשאה למפתחות API). ניהול מפתחות זמין בתוכניות Studio 8K ו-Enterprise בלבד.


המפתח מוצג פעם אחת בלבד, בעת היצירה, בתבנית cliqer_<prefix>_<secret>. יש לשמור אותו במקום מאובטח: לא ניתן לשחזר אותו, ולכן אם הוא אובד יש לבטל אותו וליצור מפתח חדש. שלחו אותו כאסימון Bearer לכל נקודת קצה של REST שמקבלת סשן:
curl -X GET "$BASE_URL/api/licenses/status?license_key=YOUR_LICENSE_KEY" \
-H "Authorization: Bearer cliqer_ab12cd34_your_secret_here"
מפתחות API פועלים בנקודות הקצה של REST בלבד. ה-WebSocket, כולל השליטה בשקפים, דורש אסימון סשן.
המפתח מאמת בתור המשתמש שיצר אותו, בהיקף הצוות והתוכנית של אותו משתמש. מפתח שבוטל או שאינו מוכר מחזיר 401, בדיוק כמו סשן חסר. נקודות קצה המיועדות למנהלים בלבד דוחות תמיד מפתחות API עם 403. על מפתחות חלות אותן מגבלות קצב כמו על בקשות סשן.
התחברות
החלפת פרטי ההתחברות של המשתמש בסשן. במקרה של הצלחה, התגובה קובעת את העוגייה session_token.
נקודת קצה: POST /api/auth/login
| פרמטר | סוג | חובה | תיאור |
|---|---|---|---|
email | string | כן | כתובת האימייל של המשתמש (גם שם משתמש של WordPress מתקבל) |
password | string | כן | סיסמת המשתמש |
otp | string | לא | קוד TOTP, כשהחשבון משתמש באפליקציית אימות |
email_otp | string | לא | קוד PIN שנשלח באימייל, כשהחשבון משתמש באימות דו-שלבי באימייל |
curl -X POST "$BASE_URL/api/auth/login" \
-H "Content-Type: application/json" \
-c cookies.txt \
-d '{"email":"user@example.com","password":"your_password"}'
interface LoginResponse {
data: {
expires: number | null // session lifetime in ms
}
}
const res: LoginResponse = await $fetch('/api/auth/login', {
method: 'POST',
body: { email: 'user@example.com', password: 'your_password' }
})
// The session_token cookie is set by the response; no token is in the body.
import requests
session = requests.Session()
data = {'email': 'user@example.com', 'password': 'your_password'}
res = session.post('$BASE_URL/api/auth/login', json=data)
# The session cookie now lives in `session`.
jar, _ := cookiejar.New(nil)
client := &http.Client{Jar: jar}
payload := map[string]string{"email": "user@example.com", "password": "your_password"}
body, _ := json.Marshal(payload)
client.Post("$BASE_URL/api/auth/login", "application/json", bytes.NewBuffer(body))
$ch = curl_init('$BASE_URL/api/auth/login');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'email' => 'user@example.com',
'password' => 'your_password'
]));
$response = curl_exec($ch);
use serde::Serialize;
#[derive(Serialize)]
struct LoginRequest { email: String, password: String }
let client = reqwest::Client::builder().cookie_store(true).build()?;
let response = client
.post("$BASE_URL/api/auth/login")
.json(&LoginRequest { email: "user@example.com".into(), password: "your_password".into() })
.send()
.await?;
תגובה (הצלחה): קובעת את העוגייה session_token ומחזירה את המטא-דאטה של הסשן.
{
"data": {
"expires": 604800000
}
}
תגובה (נדרש אימות דו-שלבי): אות 200 לבקרת זרימה, לא שגיאה. יש לשלוח שוב POST /api/auth/login עם אותם פרטי התחברות, בתוספת otp (אפליקציית אימות) או email_otp (קוד PIN שנשלח באימייל).
{
"requires_otp": true,
"method": "totp",
"email_sent": false
}
method הוא אחד מהערכים totp, email או both. עבור email, השרת שולח קוד PIN באימייל, ו-email_sent מציין אם האימייל נשלח בפועל. חשבון מסוג both מתחבר באמצעות קוד אפליקציית האימות (otp); קוד ה-PIN שנשלח באימייל אינו גורם התחברות עבורו.
401, וכך גם קוד TOTP שגוי או שתוקפו פג. גם קוד PIN שנשלח באימייל שגוי או שתוקפו פג מחזיר 401, עם אותה הודעה כמו סיסמה שגויה. חברים בארגון שמחייב כניסה יחידה (SSO) מקבלים 403 וחייבים להתחבר באמצעות SSO (ראו שאלות נפוצות על SSO).החלפת סשן
אין נקודת קצה נפרדת לרענון. השרת מחליף עבורכם את העוגייה session_token: כשסשן קרוב מספיק לתפוגה, GET /api/auth/me מגיב עם Set-Cookie חדש לצד הפרופיל. לקוח ששומר מאגר עוגיות וקורא ל-GET /api/auth/me מעת לעת נשאר מחובר ללא הגבלת זמן, בלי שום עבודה נוספת.
המשתמש הנוכחי
החזרת הפרופיל של המשתמש המאומת, או { "data": null } כשאין סשן תקף (מתאים גם לגישה אנונימית, אף פעם לא 401).
נקודת קצה: GET /api/auth/me
curl -X GET "$BASE_URL/api/auth/me" -b cookies.txt
const { data } = await $fetch('/api/auth/me')
if (data) console.log(data.email, data.is_admin)
me = session.get('$BASE_URL/api/auth/me').json()
resp, _ := client.Get("$BASE_URL/api/auth/me")
$ch = curl_init('$BASE_URL/api/auth/me');
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
$response = curl_exec($ch);
let me = client.get("$BASE_URL/api/auth/me").send().await?;
תגובה:
{
"data": {
"id": "uuid",
"email": "user@example.com",
"first_name": "Jane",
"last_name": "Doe",
"role": "uuid",
"tfa_method": "none",
"is_admin": false
}
}
התנתקות
סיום הסשן של העוגייה הנוכחית ומחיקתה מהדפדפן.
נקודת קצה: POST /api/auth/logout
curl -X POST "$BASE_URL/api/auth/logout" -b cookies.txt -c cookies.txt
await $fetch('/api/auth/logout', { method: 'POST' })
session.post('$BASE_URL/api/auth/logout')
req, _ := http.NewRequest("POST", "$BASE_URL/api/auth/logout", nil)
client.Do(req)
$ch = curl_init('$BASE_URL/api/auth/logout');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');
curl_exec($ch);
client.post("$BASE_URL/api/auth/logout").send().await?;
תגובה:
{
"success": true
}
שיטות עבודה מומלצות לאבטחה
- להשתמש ב-HTTPS בלבד: עוגיית הסשן היא
Secure; כל הבקשות חייבות להשתמש ב-TLS 1.2 ומעלה. - לעולם לא לקרוא את העוגייה מ-JavaScript: היא
HttpOnlyמתוך תכנון, וכך היא צריכה להישאר. - לרענן באופן יזום: בכרטיסיות שנשארות פתוחות לאורך זמן, יש לקרוא ל-
GET /api/auth/meלפני שתוקף הסשן פג; השרת מחליף את העוגייה עבורכם. - להתנתק כדי לבטל:
POST /api/auth/logoutמסיים את הסשן בצד השרת באופן מיידי. - לשמור פרטי התחברות, לא סשנים: אינטגרציות בין שרתים צריכות להחזיק את פרטי ההתחברות במנהל סודות וליצור סשן מחדש, ולעולם לא לשמור את העוגייה בקוד המקור.