چطور کنترل دسترسی بر اساس نقش (RBAC) را به اپ اضافه کنیم
برای افزودن کنترل دسترسی بر اساس نقش، به هر کاربر یک یا چند نقش بدهید (مثلاً مدیر، ویرایشگر، بیننده)، مشخص کنید هر نقش مجاز به کدام کارهاست، و آن مجوزها را برای هر درخواست روی سرور بررسی کنید؛ نه فقط با پنهان کردن دکمهها. همچنین بررسی کنید رکوردی که به آن دسترسی پیدا میشود متعلق به حساب یا تیم کاربر است. با چند نقش ثابت در پایگاه داده شروع کنید و با امتحان کردن دسترسی به داده کاربر دیگر، مستقیم تست کنید.
احراز هویت در برابر مجوزدهی
دو کلمهای که معمولاً قاطی میشوند:
- احراز هویت یعنی تو کی هستی؟ — ورود به سیستم. نحوه افزودن ورود به اپ را ببینید.
- مجوزدهی یعنی مجاز به چه کاری هستی؟ — کدام صفحهها، رکوردها و کارها برای کاربر واردشده در دسترس است.
RBAC رایجترین روش مجوزدهی است. مهم است: از سپتامبر ۲۰۲۶، Broken Access Control در فهرست OWASP Top 10:2025، یعنی فهرست پرکاربرد جدیترین ریسکهای امنیتی برنامههای وب، شماره یک است. خطاهای معمول اینها هستند: کاربران با تغییر یک شناسه در URL، رکورد کاربران دیگر را میخوانند، یا کاربران عادی روتهای API مخصوص مدیر را صدا میزنند.
یک مدل را انتخاب کنید
| مدل | نحوه کار | مناسب برای | مبادله |
|---|---|---|---|
| یک ستون نقش | users.role = admin / member | اپهای کوچک با دو یا سه نقش | وقتی افراد در جاهای مختلف نقشهای متفاوت دارند، بههم میریزد |
| نقشها + مجوزها | نقشها به مجوزهای نامدار نگاشت میشوند (invoices.approve)؛ کد مجوزها را بررسی میکند | اپهایی که قوانینشان رشد میکند | جدولهای بیشتر؛ فهرست مجوزها که باید نگهداری شود |
| نقشهای هر تیم (چندمستأجری) | جدول عضویت: کاربر + سازمان + نقش | SaaS که افراد به تیم یا فضای کاری تعلق دارند | هر کوئری باید به سازمان محدود شود |
| مبتنی بر ویژگی یا رابطه | قوانین روی ویژگیهای رکورد («نویسنده میتواند پست خودش را ویرایش کند») یا روابط («به اشتراک گذاشته شده با») | اسناد، اشتراکگذاری، گردشکارهای پیچیده | سختتر برای استدلال؛ کتابخانه یا سرویس اختصاصی را در نظر بگیرید |
| نقشهای ارائهدهنده احراز هویت | ارائهدهنده ورود شما نقش یا عضویت سازمانی را ذخیره میکند | اپهایی که از یک ارائهدهنده میزبانیشده استفاده میکنند | به آن ارائهدهنده وابسته است؛ باز هم روی سرور شما اعمال شود |
در عمل، بیشتر اپها دو چیز را ترکیب میکنند: نقشها برای اینکه چه نوع کارهایی میشود انجام داد، و مالکیت برای اینکه روی کدام رکوردها. «ویرایشگرها میتوانند پستها را ویرایش کنند» یک قانون نقش است؛ «…پستهای فضای کاری خودشان» یک قانون مالکیت. به هر دو نیاز دارید.
سادهتر شروع کنید از آنچه فکر میکنید. مدیر، عضو و بیننده برای تعداد شگفتانگیزی از اپها کافی است. تقسیم یک نقش بعداً سادهتر است تا باز کردن گره ده نقش که کسی نمیفهمد.
نقشها را قبل از نوشتن کد طراحی کنید
اول یک جدول مجوز را با زبان ساده بنویسید. این هم مشخصات برای هوش مصنوعی است و هم برنامه تست شما:
| کار | مالک | مدیر | عضو | بیننده |
|---|---|---|---|---|
| مشاهده پروژههای تیم | ✓ | ✓ | ✓ | ✓ |
| ساخت و ویرایش پروژهها | ✓ | ✓ | ✓ | |
| حذف پروژهها | ✓ | ✓ | ||
| دعوت و حذف افراد | ✓ | ✓ | ||
| تغییر نقشها | ✓ | |||
| صورتحساب | ✓ |
حالتهای مرزی را هم تعیین کنید: آیا آخرین مالک میتواند خارج شود؟ آیا مدیر میتواند مالک را حذف کند؟ کاربر حذفشده چه چیزی میبیند؟
مرحله به مرحله
۱. اول ورود کار کند
RBAC روی احراز هویت سوار است. سرور باید مطمئن باشد هر درخواست از چه کسی است، از یک session یا توکن تأییدشده — نه از شناسه کاربری که مرورگر در بدنه درخواست میفرستد.
۲. نقشها را در پایگاه داده ذخیره کنید
برای اپ تکتیمی، یک ستون role روی کاربران کافی است. برای تیمها، از جدول عضویت استفاده کنید:
create table memberships (
user_id uuid references users(id),
organization_id uuid references organizations(id),
role text not null check (role in ('owner','admin','member','viewer')),
primary key (user_id, organization_id)
);
هرگز نگذارید کاربران با یک بهروزرسانی عادی پروفایل، نقش خودشان را تنظیم کنند. تغییر نقش باید از یک endpoint اختصاصی و با بررسی مجوز عبور کند.
۳. بررسی مجوز را روی سرور و در یک جا انجام دهید
یک helper بنویسید — چیزی مثل can(user, 'projects.delete', project) — و آن را در هر route API، server action و job پسزمینهای که داده میخواند یا تغییر میدهد صدا بزنید. یک تابع مرکزی برای بازبینی و تست، آسانتر از بررسیهای پراکنده در کد است. بهصورت پیشفرض رد کنید: اگر هیچ قانونی اجازه ندهد، کار رد میشود.
۴. هر کوئری را محدود کنید
هر کوئری برای داده تیم باید تیم را شامل شود: where organization_id = :currentOrg، نه فقط where id = :id. این جلوی کاربری را میگیرد که /projects/123 را به /projects/124 تغییر دهد و پروژه شرکت دیگری را ببیند. برای رکوردهای تیمهای دیگر بهجای «ممنوع» پیام «پیدا نشد» برگردانید، تا وجودشان را فاش نکنید.
۵. حفاظت در سطح پایگاه داده را جایی که مهم است اضافه کنید
امنیت سطر (RLS) در Postgres به پایگاه داده اجازه میدهد تعیین کند هر کاربر کدام سطرها را ببیند. وقتی مرورگر مستقیم با پایگاه داده حرف میزند (مثل بعضی بکاندهای میزبانیشده) ضروری است، و در غیر این صورت یک لایه دوم مفید برای جدولهای حساس است.
۶. نقشها را در رابط کاربری نشان دهید
حالا چیزهایی که کاربر نمیتواند انجام دهد را پنهان یا غیرفعال کنید، تا اپ گیجکننده نباشد. این فقط برای سهولت استفاده است؛ محافظت واقعی با بررسیهای سرور است.
۷. کارهای حساس را ثبت کنید
ثبت کنید چه کسی نقشها را تغییر داد، دادهها را حذف کرد یا رکوردها را خروجی گرفت، و کی. یک لاگ حسابرسی به پاسخ دادن به سؤالات پشتیبانی و بررسی حوادث کمک میکند.
۸. مثل یک مهاجم تست کنید
با هر نقش وارد شوید و هر کاری در جدول مجوز را امتحان کنید. بعد کارهایی که نباید کار کنند را امتحان کنید: صدا زدن routeهای API مدیر بهعنوان بیننده، تغییر شناسهها در URL و درخواستها، و حذف خودتان بهعنوان آخرین مالک. وقتی قوانین ثابت شدند، نوشتن تست خودکار برای جدول مجوز ارزش دارد.
درخواستهایی که خوب جواب میدهند
کنترل دسترسی بر اساس نقش اضافه کن. نقشها برای هر سازمان: owner، admin، member، viewer، در یک جدول memberships ذخیره شوند. مجوزها در این جدول هستند: [جدول خود را اینجا بچسبانید]. یک helper سروری واحد به نام can(user, action, resource) بساز، بهصورت پیشفرض رد کن، و آن را در هر route API استفاده کن. هر کوئری را با organization_id محدود کن. کارهایی که کاربر نمیتواند انجام دهد را در رابط کاربری پنهان کن، اما هرگز برای امنیت به آن تکیه نکن.
هر route API و server function در این اپ را بازبینی کن. برای هر کدام فهرست بده چه دادهای را میخواند یا تغییر میدهد، آیا بررسی میکند کاربر واردشده است، آیا نقشش را بررسی میکند، و آیا کوئری را به سازمان یا مالکیت کاربر محدود میکند. بررسیهای جاافتاده را اضافه کن و فهرست را نشان بده.
یک صفحه /admin فقط برای مدیر اضافه کن که مالک بتواند نقش اعضا را تغییر دهد. از حذف یا تنزل آخرین مالک جلوگیری کن، هر تغییر نقش را با اینکه چه کسی و کی انجامش داده ثبت کن، و مطمئن شو endpoint تغییر نقش هر کسی که مالک نیست را رد میکند.
اشتباهات رایج
- بررسی نقش فقط در فرانتاند. API همچنان برای هر کسی که صدایش بزند باز است.
- اعتماد به شناسههای سمت کلاینت —
userIdیاroleدر بدنه درخواست بهجای session. - کوئریهای بدون محدودیت که فقط با شناسه رکورد میگیرند.
- بررسی نقش روی صفحات اما نه روی routeهای API، خروجیها، دانلود فایل یا webhook ها.
- مدیریت بر اساس ایمیل که در کد سختکد شده (
if email === 'me@...')، که آسان فراموش میشود و سخت عوض میشود. - نقشهای زیاد خیلی زود، که شش ماه بعد کسی نمیتواند توضیحشان دهد.
- sessionهای قدیمی: کاربری که تنزل یافته تا خارج شدن از سیستم دسترسی مدیر را نگه میدارد. در کارهای حساس، نقشها را از پایگاه داده بررسی کنید یا تازهسازی کنید.
چکلیست RBAC
- جدول مجوز با زبان ساده نوشته شده و حالتهای مرزی تعیین شدهاند
- سرور کاربر را از session میشناسد، نه از داده درخواست
- نقشها در پایگاه دادهاند؛ کاربران نمیتوانند نقش خودشان را عوض کنند
- یک بررسی مجوز مرکزی، بهصورت پیشفرض رد، که در هر route استفاده میشود
- هر کوئری به سازمان یا مالکیت کاربر محدود است
- امنیت سطر جایی که مرورگر به پایگاه داده دسترسی دارد
- رابط کاربری آنچه کاربر نمیتواند انجام دهد را پنهان میکند (فقط برای سهولت استفاده)
- کارهای حساس ثبت میشوند
- هر نقش تست شده، از جمله درخواستهای مستقیم API و شناسههای تغییریافته
کنترل دسترسی یکی از موارد یک فهرست بلندتر است؛ چکلیست امنیتی برای اپهای ساختهشده با هوش مصنوعی بقیه را پوشش میدهد. اگر ابزاری برای کارکنان خودتان میسازید، نحوه ساخت ابزار داخلی نشان میدهد نقشها کجا جا میگیرند.
RBAC در Mythex
Mythex برای کاربران اپ شما سیستم ورود یا نقش داخلی ارائه نمیدهد. شما یک کتابخانه احراز هویت یا ارائهدهنده انتخاب میکنید و نقشها را توصیف میکنید، و عامل آنها را در کد و پایگاه داده Postgres پروژهتان وصل میکند (افزودن ورود به اپ). نقشهای کاری Mythex، مثل Owner و Member، مشخص میکنند چه کسی میتواند پروژههای Mythex شما را ویرایش کند، نه اینکه چه کسی میتواند از اپ منتشرشده شما استفاده کند. از حالت Plan استفاده کنید تا جدول مجوز را قبل از ساخت توافق کنید، سپس از درخواست بازبینی بالا استفاده کنید و هر نقش را در Preview تست کنید، قبل از اینکه منتشر کنید. درخواستهای امنیتی در مستندات، ادامه مفیدی هستند.
پرسشها
کنترل دسترسی بر اساس نقش چیست؟
کنترل دسترسی بر اساس نقش (RBAC) تعیین میکند هر کاربر بر اساس نقشهایی که دارد، مثل مدیر، ویرایشگر یا بیننده، چه کارهایی میتواند انجام دهد. مجوزها به نقشها وصل میشوند نه به افراد، پس تغییر کاری که کسی میتواند انجام دهد فقط با تغییر نقش او انجام میشود.
تفاوت احراز هویت (authentication) و مجوزدهی (authorisation) چیست؟
احراز هویت بررسی میکند کسی کیست، معمولاً با ورود. مجوزدهی تصمیم میگیرد آن فرد واردشده چه چیزی را ببیند و انجام دهد. RBAC یکی از روشهای مجوزدهی است.
آیا مخفی کردن دکمهها در رابط کاربری برای محدود کردن دسترسی کافی است؟
نه. هر کسی میتواند مستقیم API شما را صدا بزند، پس مخفی کردن دکمه فقط چیزی که مردم میبینند را عوض میکند. هر درخواستی که داده را میخواند یا تغییر میدهد باید روی سرور با نقش کاربر و مالکیت رکورد بررسی شود.
آیا باید از امنیت سطر (row-level security) در Postgres استفاده کنم؟
امنیت سطر به خود پایگاه داده اجازه میدهد تعیین کند هر کاربر کدام سطرها را بخواند یا بنویسد. این یک تور ایمنی قوی است، بهخصوص وقتی فرانتاند مستقیم با پایگاه داده حرف میزند. این کار پیچیدگی اضافه میکند، پس بسیاری از اپها مجوزها را در کد سرور اعمال میکنند و امنیت سطر را بهعنوان لایه اضافی برای جدولهای حساس به کار میبرند.