مدیریت سطح دسترسی کاربران

  • مدرس : علی بیگدلی
  • تاریخ انتشار: 1404/06/24
  • تعداد بازدید: 2

مدیریت سطح دسترسی کاربران در GraphQL با FastAPI و JWT

در پروژه‌های GraphQL، همه درخواست‌ها معمولاً از یک endpoint واحد (/graphql) عبور می‌کنند، بنابراین مدیریت سطح دسترسی باید در Resolverها یا با استفاده از Middleware انجام شود. این کار تضمین می‌کند که کاربران تنها به بخش‌هایی از داده‌ها که مجاز هستند، دسترسی داشته باشند.

۱. تعریف نقش‌ها (Roles)

# models/users.py
from sqlalchemy import Column, Integer, String
from config.database import Base

class User(Base):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True, index=True)
    email = Column(String, unique=True, nullable=False)
    password = Column(String, nullable=False)
    role = Column(String, default="user")  # user یا admin

۲. Dependency برای بررسی نقش کاربر

# graphql/context.py
from fastapi import Header
from utils.jwt import decode_access_token
from config.database import SessionLocal
from models.users import User

def get_current_user(authorization: str = Header(None)):
    if not authorization:
        raise Exception("Missing Authorization header")
    
    token = authorization.replace("Bearer ", "")
    payload = decode_access_token(token)
    
    db = SessionLocal()
    user = db.query(User).filter(User.id == payload.get("user_id")).first()
    db.close()
    
    if not user:
        raise Exception("User not found")
    return user

def require_role(user, allowed_roles: list[str]):
    if user.role not in allowed_roles:
        raise Exception("Unauthorized: insufficient permissions")
    return True

۳. اعمال سطح دسترسی در Resolver

# graphql/tasks.py
import strawberry
from graphql.context import get_current_user, require_role
from models.tasks import Task as TaskModel
from graphql.types import TaskType

@strawberry.type
class TaskMutation:

    @strawberry.mutation
    def create_task(self, info, title: str, user_id: int) -> TaskType:
        db = info.context["db"]
        auth_header = info.context["request"].headers.get("authorization")

        current_user = get_current_user(auth_header, db)
        require_role(current_user, ["admin", "user"])
        if current_user.role != "admin" and current_user.id != user_id:
            raise Exception("Unauthorized: cannot create task for other users")

        task = TaskModel(title=title, user_id=user_id)
        db.add(task)
        db.commit()
        db.refresh(task)

        return TaskType(
            id=task.id,
            title=task.title,
            completed=task.completed,
            user_id=task.user_id,
            created_at=str(task.created_at),
            updated_at=str(task.updated_at)
        )

توضیح

  • هر کاربر دارای نقش role است، مثلاً user یا admin.
  • تابع require_role بررسی می‌کند که کاربر دسترسی لازم برای اجرای عملیات را دارد یا خیر.
  • در Resolverها می‌توان محدودیت‌های دقیق‌تری هم اعمال کرد، مثلاً اجازه ایجاد یا ویرایش فقط برای مالک داده یا مدیر سیستم.
  • می‌توان این مکانیزم را در یک Middleware یا Extension GraphQL نیز پیاده کرد تا تمام Resolverها یکدست مدیریت شوند.

با این روش، می‌توانیم کنترل دقیقی روی سطح دسترسی کاربران در تمام Query و Mutationهای GraphQL داشته باشیم و امنیت پروژه را افزایش دهیم.

ثبت دیدگاه


نکته: آدرس ایمیل شما منتشر نخواهد شد

دیدگاه کاربران (0)


هیچ دیدگاهی ثبت نشده است. می‌توانید اولین نفر باشید.