مدرس و توسعه دهنده وب . بیست چاری در حال آموزش دیدن
مدیریت دسترسی مبتنی بر نقش در NestJS
سلام دوستان
امروز میخوایم درباره یکی از موضوعات مهم و کاربردی تو دنیای برنامهنویسی وب صحبت کنیم : مدیریت دسترسی مبتنی بر نقش (RBAC) توی NestJS .
اگه تا حالا با RBAC آشنا نبودید، نگران نباشید ، تو این مقاله میخوایم به صورت کامل و جامع درباره RBAC صحبت کنیم و نحوه پیادهسازی اون توی NestJS رو بررسی کنیم . پس با من همراه باشید
مدیریت دسترسی مبتنی بر نقش (RBAC) چیه؟
مدیریت دسترسی مبتنی بر نقش (RBAC) یه روش برای کنترل دسترسی به منابع تو یه سیستمه . تو این مدل ، دسترسی به منابع مختلف بر اساس نقشهای تعیینشده برای کاربران کنترل میشه . به عبارت دیگه ، هر کاربر یا گروهی از کاربران یه نقش خاص دارن و دسترسی به منابع مختلف بر اساس این نقشها محدود یا مجاز میشه .
یه مثال ساده از RBAC
تصور کنید شما یه وبسایت با سه نقش مختلف دارید: مدیر ، کاربر معمولی و مهمان . مدیر دسترسی کامل به همه منابع سایت داره ، کاربر معمولی به برخی از منابع دسترسی داره و مهمان فقط به منابع عمومی دسترسی داره . با استفاده از RBAC ، میتونید بهطور دقیق تعیین کنید که هر نقش به چه منابعی دسترسی داره و چه عملیاتی رو میتونه انجام بده .
چرا باید از RBAC استفاده کنیم؟
استفاده از RBAC کلی مزیت داره :
- مدیریت سادهتر دسترسیها : با استفاده از نقشها بهجای مدیریت دسترسیها برای هر کاربر بهصورت جداگانه، میتونید دسترسیها رو سادهتر مدیریت کنید
- مقیاسپذیری بهتر : با اضافه کردن نقشهای جدید یا تغییر نقشهای موجود، میتونید بهراحتی مقیاسپذیری سیستم خودتون رو بهبود بدید
- امنیت بالاتر : RBAC به شما این امکان رو میده که دسترسیهای دقیقتری رو تنظیم کنید و از دسترسیهای غیرمجاز جلوگیری کنید
پیادهسازی RBAC توی NestJS
حالا که با مفهوم RBAC آشنا شدیم ، بیایید ببینیم چطور میتونیم این مدل رو توی NestJS پیادهسازی کنیم ، برای این کار، از امکانات NestJS و تکنیکهای مختلف استفاده خواهیم کرد.
مراحل پیادهسازی RBAC
- تعریف نقشها و مجوزها
- ایجاد گاردهای مبتنی بر نقش
- پیکربندی مسیرها و کنترلرها
- تعریف نقشها و مجوزها
اولین قدم برای پیادهسازی RBAC ، تعریف نقشها و مجوزهاست . برای این کار، میتونید از Enum ها و پایگاه داده استفاده کنید . برای ایجاد Enum ابتدا یه فایل به نام roles.enum.ts
ایجاد کنید و نقشها رو تعریف کنید :
export enum Role {
ADMIN = 'admin',
USER = 'user',
GUEST = 'guest',
}
خب ، حالا نوبت ایجاد مدل پایگاه داده برای نقشها و کاربر هاست . اگه از پایگاه داده استفاده میکنید ، باید مدلهای مربوط به کاربران و نقشها رو تعریف کنید . فرض کنید از TypeORM استفاده میکنید :
// user.entity.ts
import { Entity, Column, PrimaryGeneratedColumn, ManyToMany } from 'typeorm';
import { Role as RoleEntity } from './role.entity';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
username: string;
@Column()
password: string;
@ManyToMany(() => RoleEntity)
roles: RoleEntity[];
}
// role.entity.ts
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
@Entity() export class Role {
@PrimaryGeneratedColumn() id: number;
@Column() name: string;
}
توضییحات : ما دو مدل به نامهای user.entity.ts و role.entity.ts ایجاد کردیم . نکته مهمش ارتباط فیلد roles در مدل user به مدل Role هست . همین فیلد نقش هر کاربر رو در خودش نگه داری میکنه
- ایجاد گاردهای مبتنی بر نقش
گاردها تو NestJS به شما این امکان رو میدن که دسترسی به مسیرها رو بر اساس شرایط خاص کنترل کنید . برای پیادهسازی RBAC ، باید گاردهایی برای بررسی نقشها ایجاد کنید . برای این کار ، فایل roles.guard.ts
رو به این شکل ایجاد کنید :
import {
Injectable,
CanActivate,
ExecutionContext,
ForbiddenException } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Role } from './roles.enum';
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const requiredRoles = this.reflector.getAllAndOverride<Role[]>('roles',[context.getHandler(),context.getClass(),]);
if (!requiredRoles) { return true; }
const request = context.switchToHttp().getRequest();
const user = request.user;
const hasRole = () => user.roles.some((role) => requiredRoles.includes(role));
if (user && hasRole()) { return true; }
throw new ForbiddenException('Forbidden');
}
}
نکته :
ایجاد دکوراتور نقش : برای راحتتر کردن استفاده از گاردهای نقش ، میتونید یه دکوراتور ایجاد کنید . فایل roles.decorator.ts
به این شکل خواهد بود :
import { SetMetadata } from '@nestjs/common';
import { Role } from './roles.enum';
export const Roles = (...roles: Role[]) => SetMetadata('roles', roles);
- پیکربندی مسیرها و کنترلرها
حالا که گارد و دکوراتورهای نقش رو ایجاد کردیم ، باید از اونها تو مسیرها و کنترلرهای خودمون استفاده کنیم . به عنوان مثال ، فرض کنید کنترلری به نام CatsController
دارید و میخواید دسترسی به برخی از مسیرها رو بر اساس نقشها کنترل کنید . فایل cats.controller.ts
به این شکل خواهد بود :
import { Controller, Get, Post, UseGuards, Request } from '@nestjs/common';
import { Roles } from './roles.decorator';
import { RolesGuard } from './roles.guard';
import { Role } from './roles.enum';
@Controller('cats')
export class CatsController {
@Get()
@Roles(Role.ADMIN)
@UseGuards(RolesGuard)
findAll(@Request() req) {
return 'This action returns all cats';
}
@Post()
@Roles(Role.ADMIN, Role.USER)
@UseGuards(RolesGuard)
create(@Request() req) {
return 'This action adds a new cat';
}
}
تو این مثال، فقط کاربرانی با نقش ADMIN
به مسیر GET /cats
و کاربران با نقشهای ADMIN
یا USER
به مسیر POST /cats
دسترسی خواهند داشت . به همین سادگی به همین خوشمزگی :)
نکات مهم در پیادهسازی RBAC
- مدیریت نقشها و مجوزها : نقشها و مجوزها باید بهطور مداوم مدیریت و بهروز بشن . اطمینان حاصل کنید که نقشها به درستی به کاربران اختصاص داده شده و دسترسیها بهطور دقیق تنظیم شدهان
- آزمون و خطا : پیادهسازی RBAC میتونه پیچیده باشه. اطمینان حاصل کنید که تمام مسیرها و کنترلرها به درستی تست شدن و دسترسیها بهدرستی اعمال میشن
- امنیت : اطمینان حاصل کنید که کلیدهای امنیتی و تنظیمات امنیتی به درستی پیکربندی شدن و از آسیبپذیریهای احتمالی جلوگیری میشه
جمع بندی
امیدوارم با مطالعه این مقاله ، تونسته باشید با مفهوم RBAC و نحوه پیادهسازی اون توی NestJS آشنا بشید. استفاده از RBAC میتونه به شما کمک کنه تا امنیت برنامههای خودتون رو بهبود بدید و دسترسیها رو بهطور دقیق مدیریت کنید . اگه سوال یا نظری داشتید ، خوشحال میشم که با من در میان بذارید.
مخلصیم :)
مطلبی دیگر از این انتشارات
خودآموز سریع NestJS - قسمت دوم
مطلبی دیگر از این انتشارات
خودآموز سریع NestJS - قسمت اول
مطلبی دیگر از این انتشارات
موهبتی به نام NestJS