Skip to content

alina1412/drf_auth_example

Repository files navigation

Django REST Framework Educational Project

Учебный проект на Django REST Framework, демонстрирующий кастомную реализацию авторизации и ролевую модель доступа.

В рамках учебного задания реализовано:

  • ✅ Кастомная аутентификация (не встроенная DRF)
  • ✅ JWT токены с использованием библиотеки python-jose
  • ✅ Ролевая модель (admin, manager, basic, guest)
  • ✅ Декораторы для разграничения доступа
  • ✅ Тесты на pytest
  • ✅ Для настроек swagger указаны SWAGGER_SETTINGS в auth_project/settings.py

Стек технологий:

  • Python
  • Django REST Framework
  • PostgreSQL (или в тестовом режиме sqlite3)
  • JWT (кастомная реализация)
  • pytest (тестирование)
  • UV (управление зависимостями)

🚀 Установка и запуск

Предварительные требования

  • Python 3.10+
  • PostgreSQL
  • UV (менеджер пакетов; необязательно)
# Setup by UV
uv python install 3.13
uv python pin 3.13
uv sync # one command reate .venv and install dependencies 
source .venv/bin/activate

cp .env.example .env # correct variables for postgres
make db

# Run the app
make run  # or: uv run python main.py

📋 Описание

По заданию реализация авторизации не должна быть основана на встроенной возможности фреймворка, а организована своя. Для аутентификации использую выдачу JWT-токенов.

Роли пользователей:

  • admin - полный доступ ко всем ресурсам
  • manager - расширенные права на управление контентом
  • basic - базовый доступ для авторизованных пользователей
  • guest - не требует авторизации, минимальные права
  1. API имеют ограничение доступа.

Реализация доступа с помощью декоратора над каждым из методов.

пример

@require_auth_role(UserRole.BASIC)

Либо у UserRole можно указать не BASIC, а любой из остальных. У Админа - права на всё.

  1. Есть url регистрации по уникальному юзернейму и паролю
  2. Авторизация через юзернейм и пароль - равна запросу на выдачу jwt токена, который действует ограниченное время, и по которому есть доступ к другим url.
  3. Каждый пользователь может "удалить" свой профиль - запись остается в базе, но -> is_active = False. После этого доступ к url по токену прекращается, и новый "логин" не осуществляется.
  4. Изменения как обновление информации о любом пользователе или его роли может выполнять только админ, изменять информацию "о себе" кроме роли может каждый зарегистрированный (кто не гость).
  5. После изменения роли нужно перелогиниться (обновить токен).
  6. После удаления (деактивации) пользователя его токен становится недействительным.
  7. В базе минимальное количество таблиц (MVP): user, role, category, recipe. Рецепты и их категории - условные эндпоинты для сайта. Таблицы связаны: в каждой категории может быть много рецептов. Только список рецептов доступен гостю.
  8. Для запроса зарегистрированного пользователя нужно передать -H 'Authorization:bearer xxx' в хедере (или можно через соответствующую функцию в сваггере).
  9. Logout анулирует токен - нужно логиниться заново.
image image

Notes

uv venv
source .venv/bin/activate
VIRTUAL_ENV=.venv/
uv pip install ruff
uv pip list

uv add django djangorestframework

django-admin startproject myproject
python manage.py startapp api

Не называть app именем app! # for myself

делать runserver из внутренней папки


INSTALLED_APPS = [
    # ... default django apps ...
    'rest_framework',  # Add Django Rest Framework
    'api',             # Add your app
]

python manage.py makemigrations
python manage.py migrate

python manage.py migrate api zero # reverse
Get username and password from query parameters:
username = request.query_params.get('username')
password = request.query_params.get('password')

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



curl -X 'GET' \
  'http://0.0.0.0:8000/api/books-author/' \
  -H 'accept: application/json' \
  -d '' -H 'Authorization:bearer xxx' 


curl -X 'POST' \
  'http://0.0.0.0:8000/api/books-author/' \
  -H 'accept: application/json' \
  -d '' -H 'Authorization:bearer xxx' \
  -d '
  {
  "author": {
    "name": "string"
  },
  "title": "string",
  "publish_date": "2026-01-30"
}'
  

curl -X 'POST' \
  'http://127.0.0.1:8000/api/token/gen' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'X-CSRFTOKEN: 86ChJcJ8ywmz6fKsWNhUFQNssTok7P5Y' \
  -d '{
  "username": "joe",
  "password": "123"
}'

curl -X 'POST' 'http://0.0.0.0:8000/v1/?username=joe&password=123'


get username and password from body in view
username = request.data.get("username")
password = request.data.get("password")



curl -X 'POST' \
  'http://127.0.0.1:8000/api/register' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'X-CSRFTOKEN: 86ChJcJ8ywmz6fKsWNhUFQNssTok7P5Y' \
  -H 'X-Client-Secret:xxx' \
  -d '{
  "username": "joe",
  "password": "123"
}'



curl -X 'POST' \
  'http://127.0.0.1:8000/api/edit-role' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '' -H 'Authorization:bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImpvZSIsImV4cGlyZSI6IjIwMjYtMDEtMzBUMTM6NDI6NDcuNDA5Njk4KzAwOjAwIiwicm9sZSI6ImFkbWluIn0.XWL-iV5jUq5Or7_jy2kI2NrN7oLv5G33ay7UvheBcDU' \
  -d '{
  "role_id": 5,
  "id": 1
}'


curl -X 'POST' \
  'http://127.0.0.1:8000/api/edit-role' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '' -H 'Authorization:bearer xxx' \
  -d '{
  "role_id": 5,
  "id": 1
}'


curl -X 'DELETE' \
  'http://127.0.0.1:8000/api/profile/1/' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '' -H 'Authorization:bearer xxx' \
  -d '{
  "role_id": 5,
  "id": 1
}'

About

educational django rest framework project

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Generated from alina1412/drf_example