ابرووا
شروع رایگان
☰ فهرست مستندات · claimهای سفارشی

claimهای سفارشی (custom claims)

نمایش Markdown

اطلاعاتی درباره‌ی کاربر را در همه‌ی توکن‌هایش بگذارید: طرح اشتراک، نقش، تیم‌هایی که عضو آن‌هاست. سرور شما آن‌ها را با کلید سرور می‌گذارد، قوانین امنیتی Sync آن‌ها را می‌خوانند و اپ با آن‌ها صفحه‌ی درست را نشان می‌دهد. همان مدل custom claims در Firebase.

یک واقعیت که همه‌ی محصولات به آن اعتماد می‌کنند.

کاربری در سایت شما پرداخت کرده و حالا اپ باید درس‌های ویژه را برایش باز کند. فروشگاهی بعضی کاربران را کارمند می‌داند. اپ سازمانی می‌داند کاربر عضو کدام تیم‌هاست. claimهای سفارشی چنین اطلاعاتی را امضاشده داخل توکن کاربر می‌برند، پس همه‌ی محصولات ابرووا به آن‌ها اعتماد می‌کنند و اپ نمی‌تواند عوضشان کند. اگر custom claims در Firebase را می‌شناسید، این هم همان‌طور کار می‌کند.

چطور کار می‌کند#

  1. سرور شما claimها را برای کاربر می‌گذارد، با کلید سرور پروژه: setCustomUserClaims(userId, { plan: 'pro' }).
  2. هر توکن تازه‌ی آن کاربر آن‌ها را دارد، در سطح اول توکن کنار sub و exp. کاربر توکن تازه را در ورود یا تمدید بعدی می‌گیرد (حداکثر تا یک ساعت)، یا همان لحظه وقتی اپ توکن تازه بخواهد.
  3. قوانین امنیتی Sync آن‌ها را می‌خوانند، به شکل auth.token.plan، و اپ آن‌ها را می‌خواند با getTokenResult() تا صفحه‌ی درست را نشان دهد.

این‌که کاربر چطور پرداخت کرده یا چرا کارمند است کار خود شماست: ابرووا فقط نتیجه را می‌برد.

مرحله ۱: گذاشتن claimها روی سرور#

با SDK مدیریتی برای Node.js:

ts
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:

bash
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 و نگه داشتن بقیه، اول آن‌ها را بخوانید:

ts
const user = await auth.getUser(userId);
await auth.setCustomUserClaims(userId, { ...user.customClaims, beta: true });

برای پاک کردن همه‌ی claimها null (یا {}) بفرستید:

ts
await auth.setCustomUserClaims(userId, null);

مرحله ۲: استفاده در قوانین امنیتی#

قوانین Sync هر claim را به شکل auth.token.<name> می‌خوانند، مقدارهای تودرتو هم. claim متنی با نام role به شکل auth.role هم در دسترس است:

json
{
  "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های ابرووا احراز هویت:

ts
// Web، React Native
const result = await auth.getTokenResult();
if (result?.claims.plan === 'pro') showProBadge();
dart
// Flutter
final result = await auth.getTokenResult();
if (result?.claims['plan'] == 'pro') showProBadge();
swift
// iOS
let result = try await AbrovaAuth.shared.getTokenResult()
if result?.claims["plan"] as? String == "pro" { showProBadge() }
kotlin
// 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 تغییرکرده با توکن بعدی به اپ می‌رسد، حداکثر تا یک ساعت. برای گرفتن آن همان لحظه، مثلاً با دکمه‌ی «بررسی خرید من» یا وقتی اپ باز می‌شود، توکن تازه بخواهید:

ts
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ها را در همان جای توکن می‌گذارند، پس قوانین آن‌ها را به همان شکل می‌خوانند.
این صفحه مفید بود؟
گزارش مشکل

به‌روزرسانی: ۱۴ آبان ۱۴۰۵