• صفحه اصلی
  • مهارت‌ها
  • پروژه‌ها
  • بلاگ
  • مشاوره
  • تماس با من
مشاورهرزومه
Naser Rasouli

نویسنده

Naser Rasouli

توسعه‌دهنده فرانت‌اند؛ اینجا تجربه‌ها و یادداشت‌های واقعی‌ام از پروژه‌ها را می‌نویسم.

GitHubLinkedIn

آخرین نوشته‌ها

تسلط بر Record در تایپ‌اسکریپت
2025-12-13•1 دقیقه مطالعه

تسلط بر Record در تایپ‌اسکریپت

یک راه تمیز برای مپ‌کردن enum و union به لیبل، آیکن و رنگ با Record در تایپ‌اسکریپت.

Conventional Commits: پیام‌های بهتر برای Git
2025-12-12•1 دقیقه مطالعه

Conventional Commits: پیام‌های بهتر برای Git

راهنمای سریع Conventional Commits برای داشتن تاریخچهٔ خوانا، اتوماسیون انتشار و چنج‌لاگ‌های دقیق.

تسلط به Git Flow
2025-12-08•1 دقیقه مطالعه

تسلط به Git Flow

یک راهنمای خلاصه و خودمانی برای شاخه‌بندی و مرج تمیز با Git Flow.

RBAC استاتیک در React: نقش‌ها و دسترسی‌ها

RBAC استاتیک در React: نقش‌ها و دسترسی‌ها

2025-12-20
reactjsrbacaccess-controlpermissions

مقدمه

ساختن پنل ادمین یعنی تصمیم بگیرید چه کسی چه چیزی را ببیند یا انجام بدهد. یک رویکرد استاتیک ساده — نقش‌ها و دسترسی‌ها داخل کد و نه از API — برای پروژه‌های کوچک/متوسط کافی است. این الگو نشان می‌دهد چطور هم روت‌ها و هم کنترل‌های UI را نگه دارید و بعداً اگر خواستید پویا کنید، آماده باشید.

چی را پوشش می‌دهیم

  • تعریف نقش‌ها، صفحات و دسترسی‌ها در یک جا
  • محافظت از روت‌ها تا فقط نقش‌های مجاز وارد شوند
  • نمایش یا پنهان‌کردن اکشن‌های UI بر اساس دسترسی

۱) تعریف نقش‌ها و دسترسی‌ها

همه‌چیز را در یک roles.ts نگه دارید تا منطق پخش نشود.

// roles.ts
export const ROLES = {
  ADMIN: "ADMIN",
  EDITOR: "EDITOR",
  VIEWER: "VIEWER",
} as const;

export const PERMISSIONS = {
  USER_CREATE: "USER_CREATE",
  USER_DELETE: "USER_DELETE",
  USER_VIEW: "USER_VIEW",
} as const;

export const roleAccess = {
  [ROLES.ADMIN]: ["dashboard", "users", "settings"],
  [ROLES.EDITOR]: ["dashboard", "users"],
  [ROLES.VIEWER]: ["dashboard"],
};

export const rolePermissions = {
  [ROLES.ADMIN]: [
    PERMISSIONS.USER_CREATE,
    PERMISSIONS.USER_DELETE,
    PERMISSIONS.USER_VIEW,
  ],
  [ROLES.EDITOR]: [PERMISSIONS.USER_VIEW],
  [ROLES.VIEWER]: [PERMISSIONS.USER_VIEW],
};

این می‌شود منبع واحد: هر نقش به کدام صفحه می‌رود و چه اکشنی می‌تواند انجام دهد.


۲) کنترل سطح روت با ProtectedRoute

اگر نقش کاربر مجاز نیست، اجازهٔ ورود به صفحه ندهید.

// ProtectedRoute.tsx
import { Navigate } from "react-router-dom";
import { useAuth } from "@/hooks/useAuth";
import { roleAccess, ROLES } from "./roles";

export function ProtectedRoute({
  children,
  allowed,
}: {
  children: JSX.Element;
  allowed: string[];
}) {
  const { role } = useAuth();

  if (!role || !allowed.includes(role)) {
    return <Navigate to="/unauthorized" replace />;
  }

  return children;
}

در تنظیمات روت استفاده کنید:

// routes.tsx
import { ProtectedRoute } from "./ProtectedRoute";
import { roleAccess, ROLES } from "./roles";
import DashboardPage from "@/features/dashboard/pages/DashboardPage";
import UsersPage from "@/features/users/pages/UsersPage";

export const routes = [
  {
    path: "/dashboard",
    element: (
      <ProtectedRoute allowed={roleAccess[ROLES.VIEWER]}>
        <DashboardPage />
      </ProtectedRoute>
    ),
  },
  {
    path: "/users",
    element: (
      <ProtectedRoute allowed={roleAccess[ROLES.EDITOR]}>
        <UsersPage />
      </ProtectedRoute>
    ),
  },
];

فقط نقش‌هایی که در roleAccess آمده‌اند به صفحه می‌رسند.


۳) کنترل سطح کامپوننت با AccessControl

اکشن‌های UI را بر اساس دسترسی نشان دهید یا پنهان کنید.

// AccessControl.tsx
import { ReactNode } from "react";
import { useAuth } from "@/hooks/useAuth";
import { rolePermissions } from "./roles";

type Props = {
  permission: string;
  children: ReactNode;
};

export function AccessControl({ permission, children }: Props) {
  const { role } = useAuth();
  if (!role) return null;

  const permissions = rolePermissions[role] || [];
  return permissions.includes(permission) ? <>{children}</> : null;
}

نمونهٔ استفاده داخل صفحه:

import { AccessControl } from "@/components/AccessControl";
import { PERMISSIONS } from "@/routes/roles";

function UsersPage() {
  return (
    <div>
      <h1>User List</h1>

      <AccessControl permission={PERMISSIONS.USER_CREATE}>
        <button>Add User</button>
      </AccessControl>

      <AccessControl permission={PERMISSIONS.USER_DELETE}>
        <button>Delete User</button>
      </AccessControl>
    </div>
  );
}

خلاصه

  • نقش‌ها، روت‌ها و دسترسی‌ها را در یک ماژول (roles.ts) نگه دارید.
  • با ProtectedRoute ناوبری را امن کنید.
  • با AccessControl اکشن‌های UI را محدود کنید.
  • از استاتیک شروع کنید؛ بعداً می‌توانید roleAccess و rolePermissions را با دادهٔ API عوض کنید.

جمع‌بندی

با چند کمک‌کنندهٔ سبک، کنترل دسترسی متمرکز و قابل پیش‌بینی دارید؛ هم برای امروز تمیز است و هم فردا می‌توانید به نسخهٔ داینامیک مهاجرت کنید. کدنویسی‌تان پرانرژی! 🚀