☰ فهرست مستندات · claimهای سفارشی
claimهای سفارشی (custom claims)
اطلاعاتی دربارهی کاربر را در همهی توکنهایش بگذارید: طرح اشتراک، نقش، تیمهایی که عضو آنهاست. سرور شما آنها را با کلید سرور میگذارد، قوانین امنیتی Sync آنها را میخوانند و اپ با آنها صفحهی درست را نشان میدهد. همان مدل custom claims در Firebase.
کاربری در سایت شما پرداخت کرده و حالا اپ باید درسهای ویژه را برایش باز کند. فروشگاهی بعضی کاربران را کارمند میداند. اپ سازمانی میداند کاربر عضو کدام تیمهاست. claimهای سفارشی چنین اطلاعاتی را امضاشده داخل توکن کاربر میبرند، پس همهی محصولات ابرووا به آنها اعتماد میکنند و اپ نمیتواند عوضشان کند. اگر custom claims در Firebase را میشناسید، این هم همانطور کار میکند.
چطور کار میکند#
- سرور شما claimها را برای کاربر میگذارد، با کلید سرور پروژه:
setCustomUserClaims(userId, { plan: 'pro' }). - هر توکن تازهی آن کاربر آنها را دارد، در سطح اول توکن کنار
subوexp. کاربر توکن تازه را در ورود یا تمدید بعدی میگیرد (حداکثر تا یک ساعت)، یا همان لحظه وقتی اپ توکن تازه بخواهد. - قوانین امنیتی Sync آنها را میخوانند، به شکل
auth.token.plan، و اپ آنها را میخواند باgetTokenResult()تا صفحهی درست را نشان دهد.
اینکه کاربر چطور پرداخت کرده یا چرا کارمند است کار خود شماست: ابرووا فقط نتیجه را میبرد.
مرحله ۱: گذاشتن claimها روی سرور#
با SDK مدیریتی برای Node.js:
import { initAdmin } from '@abrova/auth-admin';
const auth = initAdmin(); // ABROVA_PROJECT_ID، ABROVA_API_KEY و ABROVA_SERVER_SECRET را میخواند
// بعد از اینکه سرور شما پرداخت را تأیید کرد:
await auth.setCustomUserClaims(userId, { plan: 'pro', levels: ['L1', 'L2'] });یا با هر زبانی، با یک درخواست HTTPS:
curl -X PUT "https://auth-users.abrova.ir/v1/projects/$PROJECT_ID/users/$USER_ID/custom-claims" \
-H "x-api-key: $ABROVA_API_KEY" \
-H "x-server-secret: $ABROVA_SERVER_SECRET" \
-H "content-type: application/json" \
-d '{"claims": {"plan": "pro", "levels": ["L1", "L2"]}}'userId شناسهی کاربر ابرووا احراز هویت است (ru_...)، همان که اپ بعد از ورود میگیرد.
گذاشتن claim کلید سرور (ab_srv_...) میخواهد. هرگز آن را در اپ یا صفحهی وب نگذارید، وگرنه هر کسی میتواند هر claimی به خودش بدهد. اپ فقط میتواند claimها را بخواند، نه بگذارد.
گذاشتن claimها جایگزین میکند#
هر فراخوانی همهی claimهای کاربر را جایگزین میکند، مثل Firebase. برای اضافه کردن یک claim و نگه داشتن بقیه، اول آنها را بخوانید:
const user = await auth.getUser(userId);
await auth.setCustomUserClaims(userId, { ...user.customClaims, beta: true });برای پاک کردن همهی claimها null (یا {}) بفرستید:
await auth.setCustomUserClaims(userId, null);
مرحله ۲: استفاده در قوانین امنیتی#
قوانین Sync هر claim را به شکل auth.token.<name> میخوانند، مقدارهای تودرتو هم. claim متنی با نام role به شکل auth.role هم در دسترس است:
{
"rules": {
"lessons": {
"$id": {
".read": "auth.token.plan === 'pro' || data.free === true"
}
},
"teams": {
"$team": {
".write": "auth.token.teams.includes($team) && auth.token.team.role === 'editor'"
}
}
}
}کاربری که آن claim را ندارد از بررسی نمیگذرد. قوانین امنیتی Sync را ببینید.
مرحله ۳: خواندن در اپ#
getTokenResult() توکن را با فیلدهای بازشدهاش برمیگرداند، مثل getIdTokenResult() در Firebase. با آن صفحهی درست را نشان دهید (نشان «Pro»، درسهای بازشده). از نسخهی 0.2.0 SDKهای ابرووا احراز هویت:
// Web، React Native const result = await auth.getTokenResult(); if (result?.claims.plan === 'pro') showProBadge();
// Flutter final result = await auth.getTokenResult(); if (result?.claims['plan'] == 'pro') showProBadge();
// iOS
let result = try await AbrovaAuth.shared.getTokenResult()
if result?.claims["plan"] as? String == "pro" { showProBadge() }// Android
val result = AbrovaAuth.shared.getTokenResult()
if (result?.claims?.get("plan") == "pro") showProBadge()| فیلد | چیست |
|---|---|
| token | خود access token، همان که getToken() میدهد. |
| claims | همهی فیلدهای توکن: sub (شناسهی کاربر)، pid، iat، exp، auth_time، amr و claimهای سفارشی شما. |
| expirationTime | زمان انقضای این توکن (در iOS: expirationDate، در Android: expirationTimestamp). |
| issuedAtTime | زمان صدور این توکن (در iOS: issuedAtDate، در Android: issuedAtTimestamp). |
| authTime | زمان ورود کاربر. تمدید آن را عوض نمیکند (در iOS: authDate، در Android: authTimestamp). |
| signInProvider | کاربر چطور وارد شده: anonymous، apple، google، password، magic_link یا telegram. |
اپ توکن خودش را میتواند بخواند، ولی تصمیم دسترسی فقط در اپ هیچوقت امن نیست. صفحهها را با getTokenResult() نشان دهید و داده را با قوانین امنیتی محافظت کنید که توکن امضاشده را روی سرور بررسی میکنند.
گرفتن claimهای تازه همان لحظه#
claim تغییرکرده با توکن بعدی به اپ میرسد، حداکثر تا یک ساعت. برای گرفتن آن همان لحظه، مثلاً با دکمهی «بررسی خرید من» یا وقتی اپ باز میشود، توکن تازه بخواهید:
await auth.getTokenResult({ forceRefresh: true });بعد به ابرووا سینک بگویید از آن استفاده کند: sync.refreshUserToken().
claim چه چیزی میتواند داشته باشد#
| قاعده | حد |
|---|---|
| مقدارها | JSON: متن، عدد، true / false، null، فهرست و شیء. |
| تودرتو | فهرستها و شیءها داخل هم، حداکثر ۵ سطح. |
| اندازه | همهی claimهای یک کاربر روی هم حداکثر ۱۰۰۰ بایت، به صورت JSON. |
| نامها | تا ۶۴ کاراکتر. نامهایی که خود توکن استفاده میکند رد میشوند، مثلاً sub، iss، aud، iat، exp، nbf، jti، auth_time و amr (پیام خطا نامی را که رد شد میگوید). |
درخواست ردشده با 400 INVALID_CLAIMS و اولین مشکل جواب میگیرد و چیزی عوض نمیشود.
توکن امضا شده ولی رمزگذاری نشده است: هر کسی که دستگاه را دارد میتواند آن را بخواند. نقش، طرح اشتراک و شناسه را در claim بگذارید. هرگز ایمیل، شماره تلفن، قیمت یا کلید را نگذارید.
خوب است بدانید#
- در همهی طرحها. claimها هزینهی اضافه ندارند: کاربری که claim دارد هنوز یک کاربر فعال ماهانه است.
- نشستها میمانند. تغییر claimها هیچوقت کاربر را خارج نمیکند. برای قطع دسترسی کاربر از revokeRefreshTokens استفاده کنید یا کاربر را در کنسول غیرفعال کنید.
- کاربران ناشناس هم میتوانند claim داشته باشند و وقتی به حساب کامل ارتقا پیدا میکنند آنها را نگه میدارند.
- شنوندههای باز Sync claimهای قبلی را نگه میدارند تا وقتی تمدید شوند، حداکثر ۲۴ ساعت. برای محتوای پولی که کاربر ممکن است از دست بدهد، claim را در یک خواندن معمولی هم بررسی کنید، یا وقتی سرور شما claim را برمیدارد شنونده را در اپ ببندید.
- در کنسول، بخش ابرووا احراز هویت › کاربران کاربرانی را که claim دارند علامت میزند و claimها را فقطخواندنی نشان میدهد. هر تغییر در فعالیتها با عنوان «ادعاهای سفارشی تغییر کرد» و بدون مقدارها دیده میشود.
- توکنهایی که سرور خودتان میسازد (
POST /users/tokenباclaims) همین قاعدهها را دارند و claimها را در همان جای توکن میگذارند، پس قوانین آنها را به همان شکل میخوانند.
بهروزرسانی: ۱۴ آبان ۱۴۰۵