Skip to content

Lu7474/custom-auth-rbac-api

Repository files navigation

Custom Auth & RBAC API

REST API на Django/DRF с собственной JWT-аутентификацией, middleware-обработкой токенов и ролевой моделью доступа (RBAC). Написан без django.contrib.auth — чтобы показать понимание того, как аутентификация и авторизация работают изнутри.

Почему без django.contrib.auth

Встроенный auth Django решает большинство задач, и в production я бы его использовал. Здесь — намеренный выбор: разобрать механику до уровня "как это устроено": кастомная модель пользователя, bcrypt-хеширование паролей вручную, JWT без AbstractUser, middleware вместо DRF-аутентификаторов. В разделе Что изменил бы в production объясняю, где такой подход не стал бы применять.


Стек

  • Python 3.13 / Django 6.0 / DRF 3.16
  • PyJWT — генерация и валидация токенов
  • bcrypt — хеширование паролей
  • SQLite (переключается через DATABASE_URL)

Архитектура

Доступ строится на четырёх сущностях:

Сущность Роль
CustomUser Пользователь с bcrypt-хешем пароля и ссылкой на роль
Role Справочник ролей (Admin, User, ...)
BusinessElement Ресурс/модуль системы (mock_objects, access_rules)
AccessRule CRUD-флаги (can_read/create/update/delete) для пары (Role, BusinessElement)

Поток запроса:

Request
  → CustomAuthMiddleware   # читает Authorization: Bearer <token>,
                           # декодирует JWT, кладёт user в request.custom_user
  → View
      → @check_access(element_key, action)   # проверяет AccessRule перед логикой

Схема данных

Role ──────────┐
               ├── AccessRule (can_read, can_create, can_update, can_delete)
BusinessElement┘

CustomUser ──── Role

Структура проекта

├── core/           # JWT (auth.py), middleware, декоратор @check_access
├── users/          # Регистрация, логин, профиль
├── access/         # Модели ролей/ресурсов/правил, API просмотра правил
├── mock/           # Пример защищённых бизнес-ресурсов
├── config/         # settings.py, urls.py
└── init_db.py      # Заполнение БД начальными данными

Запуск

Локально

git clone https://github.com/Lu7474/custom-auth-rbac-api.git
cd custom-auth-rbac-api
pip install -r requirements.txt
python manage.py makemigrations users access mock
python manage.py migrate
python init_db.py
python manage.py runserver

Docker

docker-compose up --build

Сервер будет доступен на http://localhost:8000.


API

Аутентификация

Метод URL Описание
POST /api/users/register/ Регистрация
POST /api/users/login/ Получить JWT-токен
GET /api/users/profile/ Профиль текущего пользователя
PATCH /api/users/profile/ Обновить профиль
DELETE /api/users/profile/ Soft-delete аккаунта

Защищённые ресурсы

Метод URL Требуемое право
GET /api/mock/ mock_objects:read
POST /api/mock/ mock_objects:create
GET /api/access/rules/ access_rules:read

Начальные данные (init_db.py)

Роль Ресурс Read Create Update Delete
Admin mock_objects
Admin access_rules
User mock_objects

Тестовый администратор: admin@example.com / admin123


Примеры запросов

Логин:

curl -s -X POST http://localhost:8000/api/users/login/ \
  -H "Content-Type: application/json" \
  -d '{"email":"admin@example.com","password":"admin123"}'
# → {"token": "eyJ..."}

Запрос к защищённому ресурсу:

TOKEN="<token из логина>"
curl -s http://localhost:8000/api/mock/ \
  -H "Authorization: Bearer $TOKEN"

Создание объекта (требует роль Admin):

curl -s -X POST http://localhost:8000/api/mock/ \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'

Регистрация:

curl -s -X POST http://localhost:8000/api/users/register/ \
  -H "Content-Type: application/json" \
  -d '{"email":"user@example.com","password":"pass123","password_confirm":"pass123","first_name":"Ivan","last_name":"Petrov"}'

Тесты

python manage.py test

Покрывают:

  • регистрацию (успех, несовпадение паролей, дубль email)
  • логин (успех, неверный пароль, несуществующий пользователь, inactive-аккаунт)
  • невалидный и просроченный JWT
  • профиль без токена и с токеном
  • матрицу прав: Admin vs User на mock_objects и access_rules

Что изменил бы в production

  • Auth-слой — не писал бы свой полностью. django.contrib.auth + djangorestframework-simplejwt надёжнее и поддерживаются сообществом. Кастомный auth оправдан только при жёстких ограничениях на зависимости.
  • RBAC — оставил бы кастомным: встроенные пермишены Django не дают нужной гранулярности по бизнес-ресурсам.
  • JWT-секрет — обязательно в переменную окружения, не хардкод в коде.
  • SQLite → PostgreSQL для любой prod-нагрузки.
  • Тесты — добавил бы property-based тесты для матрицы прав и интеграционные тесты с реальной БД.

Учебно-архитектурный проект. Цель — разобраться с механикой auth/authz на уровне реализации, а не заменить готовые решения.

About

Django REST API с кастомной JWT-аутентификацией и системой управления доступом на основе ролей (RBAC). Реализовано без использования встроенных механизмов Django auth.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors