JavaRush /Курси /Модуль 3: Django /Обмеження доступу до ендпоінтів на основі ролей

Обмеження доступу до ендпоінтів на основі ролей

Модуль 3: Django
Рівень 21 , Лекція 5
Відкрита

Роль — це категорія користувачів, яка визначає їх рівень доступу до функціоналу вашого застосунку. Ролі допомагають розділити права доступу для різних типів користувачів, наприклад:

  • Адміністратор: доступ до адміністративних функцій.
  • Редактор: доступ до створення та редагування контенту.
  • Користувач: доступ лише до базового функціоналу застосунку.

У реальних проєктах ролевий доступ використовується майже всюди: від корпоративних систем до онлайн-магазинів та соціальних мереж. Ролі роблять систему більш безпечною, зрозумілою та керованою. Наприклад, в інтернет-магазині адміністратор може бачити всі замовлення, а продавець — лише свої.

Реалізація ролей у проєкті Django

Спочатку створимо модель Role, щоб зберігати доступні ролі у базі даних. Вона буде пов'язуватися з моделлю користувача через зв'язок ForeignKey.

Відкриємо додаток, де у нас розташовані моделі користувачів (наприклад, додаток accounts).

# accounts/models.py

from django.contrib.auth.models import AbstractUser
from django.db import models

class Role(models.Model):
    name = models.CharField(max_length=64, unique=True)  # Назва ролі (наприклад, 'admin', 'editor')
    description = models.TextField(blank=True)  # Опис ролі (опціонально)

    def __str__(self):
        return self.name


class CustomUser(AbstractUser):
    role = models.ForeignKey(Role, on_delete=models.SET_NULL, null=True, blank=True)  # Роль користувача

Пояснення коду:

  1. Ми додаємо модель Role, яка містить назву ролі (name) та її опис (description).
  2. У стандартну модель користувача (AbstractUser) ми додали поле role, яке посилається на модель Role. Таким чином, у кожного користувача буде своя роль (або її відсутність).

Тепер створимо і застосуємо міграції:

python manage.py makemigrations
python manage.py migrate

Додавання ролей через Django Admin

Тепер додамо модель Role в адмін-зону, щоб ролі можна було створювати і керувати ними:

# accounts/admin.py

from django.contrib import admin
from .models import Role, CustomUser

admin.site.register(Role)
admin.site.register(CustomUser)

Після цього зайдіть в адмін-зону Django і створіть кілька ролей:

  1. Адміністратор (admin).
  2. Редактор (editor).
  3. Користувач (user).

Створення кастомного дозволу на основі ролей

Тепер створимо кастомний дозвіл для перевірки ролей користувача. Для цього напишемо клас дозволу у файлі permissions.py:

# accounts/permissions.py

from rest_framework.permissions import BasePermission

class RolePermission(BasePermission):
    """
    Кастомний дозвіл для перевірки ролей користувача.
    """
    allowed_roles = []  # Список дозволених ролей

    def has_permission(self, request, view):
        user = request.user

        # Перевіряємо, що користувач аутентифікований
        if not user.is_authenticated:
            return False

        # Перевіряємо, що роль користувача входить у список дозволених ролей
        if user.role and user.role.name in self.allowed_roles:
            return True

        return False
  1. Клас RolePermission наслідується від BasePermission.
  2. Ми визначаємо список дозволених ролей у атрибуті allowed_roles (наприклад, ['admin', 'editor']).
  3. Метод has_permission повертає True, якщо користувач має одну з дозволених ролей, інакше — False.

Використання кастомного дозволу у представленнях

Тепер застосуємо наш дозвіл у представленні. Наприклад, у нас є API для управління статтями, до якого повинні мати доступ тільки користувачі з ролями admin або editor.

# articles/views.py

from rest_framework.views import APIView
from rest_framework.response import Response
from accounts.permissions import RolePermission

class ArticleView(APIView):
    """
    Ендпоінт для роботи зі статтями.
    Доступ дозволений тільки для ролей 'admin' і 'editor'.
    """
    permission_classes = [RolePermission]
    RolePermission.allowed_roles = ['admin', 'editor']  # Задаємо дозволені ролі

    def get(self, request):
        return Response({"message": "Доступ дозволений для адміністраторів і редакторів!"})

Тепер, якщо користувач з роллю, наприклад, user, спробує звернутися до цього ендпоінту, він отримає помилку 403 Forbidden.

Додаткові аспекти ролевої моделі

У деяких випадках потрібно налаштувати доступ для різних ендпоінтів або операцій всередині одного представлення. Наприклад, адміністратор може читати, створювати і видаляти статті, а редактор — тільки читати і редагувати.

Для цього розділимо операції за ролями:

# articles/permissions.py

class RolePermissionWithActions(BasePermission):
    """
    Кастомний дозвіл для перевірки ролей з урахуванням типів операцій.
    """
    role_action_map = {}  # Словник з ролями та дозволеними діями

    def has_permission(self, request, view):
        user = request.user

        # Перевіряємо, що користувач автентифікований
        if not user.is_authenticated:
            return False

        # Визначаємо дію (метод HTTP-запиту)
        action = request.method.lower()

        # Перевіряємо, що роль користувача дозволяє поточну дію
        if user.role and action in self.role_action_map.get(user.role.name, []):
            return True

        return False

Тепер у вашому представленні ви можете задати дозволені дії для кожної ролі:

# articles/views.py

from articles.permissions import RolePermissionWithActions

class MultiActionArticleView(APIView):
    """
    Ендпоінт для роботи зі статтями.
    Доступ до операцій залежить від ролі користувача.
    """
    permission_classes = [RolePermissionWithActions]
    RolePermissionWithActions.role_action_map = {
        'admin': ['get', 'post', 'delete'],  # Адміністратор: читати, створювати, видаляти
        'editor': ['get', 'put'],  # Редактор: читати, редагувати
    }

    def get(self, request):
        return Response({"message": "Читання статті."})

    def post(self, request):
        return Response({"message": "Створення статті."})

    def delete(self, request):
        return Response({"message": "Видалення статті."})

Тестування ролевої моделі

Тепер протестуємо наші дозволи. Для цього ми можемо використовувати Postman або будь-який інший клієнт для роботи з API. Спробуйте зайти на ендпоінти під різними користувачами і переконайтеся, що доступ працює згідно з ролями.

Як це допомагає в реальному житті?

Налаштування ролевої моделі корисне в будь-якому проєкті, де є розподіл прав доступу. Наприклад:

  • У корпоративній CRM системі ролі допомагають ізолювати дані між співробітниками різних відділів.
  • В онлайн-магазині доступ до адміністративної панелі обмежується лише для співробітників магазину.
  • У соціальних мережах — права модераторів дозволяють модерувати контент, недоступний для звичайних користувачів.

Бонус: на співбесідах вміння реалізувати ролеву модель — це часто зустрічається питання, тому не забудьте підготувати історії про те, як ви це освоїли і впровадили!

Тепер ви офіційно готові додавати ролі у своє API! 🎉

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ