В этой короткой серии статей я хотел бы поделиться тем, как реализовать гранулированные, контроль доступа на основе ролей ресурсов в Django. Мы построим API для отдыха, которая возвращает 401-е годы (несанкционированные) для неавторизованных пользователей, 404S для аутентифицированных пользователей, не разрешенных для просмотра данных ресурсов, и 403s (запрещенных) для пользователей, уполномоченных для просмотра ресурсов, но запрещено выполнять заданные действия.
Мы будем использовать ваниль Джанго без дополнительных рамок или зависимостей во всем. Это не значит, что вы не должны использовать публично доступные пакеты, но придерживаясь чистого Django – хороший выбор, когда вы хотите изучать вещи и когда вам нужна самая гибкость. Помните, однако, что аутентификация пользователя – это одно место, где вы не хотите беспорядок: чем больше пишет код, лучший тестовый люкс, который вам понадобится!
В этой части один мы настроим проект Django и приложение для нашего API для отдыха. Мы добавим пользовательскую модель пользователей и простые тесты. Вы можете найти сопроводительный код В этом репозитории Отказ
Создание проекта и приложения
Для начала давайте создадим новую папку и виртуальную среду. Я использую Пьенв Виртуальский
Создать виртуальную среду:
$ mkdir django-rbac && cd django-rbac $ pyenv virtualenv 3.8.1 django-rbac-3.8.1 $ pyenv local django-rbac.3.8.1
Давайте установим Django и создать проект под названием rbac.
:
# django-rbac/ $ printf "django==3.1.7\n" > requirements.txt $ pip install -r requirements.txt $ django-admin startproject rbac .
Модифицировать settings.py
Так что он содержит только приложения и HedmostWares, нам нужно:
# rbac/settings.py INSTALLED_APPS = [ 'rbac.core', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', ]
Мы создадим rbac.Core
приложение вскоре ниже. Мы используем Django’s Система аутентификации Для аутентификации пользователей, который требует от нас, чтобы включить django.contrib.auth
приложение и django.contrib.auth.middleware. Аутентификация Moddleware
промежуточное ПО. Нам тоже нужно django.contrib.sessions
приложение и Sessionmiddleware
для управления пользовательскими сессиями. Мы также включаем Commonmiddleware
и SecurityMiddleware
Даже если не строго требуется.
Наши взгляды и модели будут жить под Core
приложение. Давайте создадим такое приложение и переместите его под rbac.
:
$ python manage.py startapp core $ mv core rbac/
Я перемещаю приложение под проектом, чтобы все осталось в одном месте. Я не ожидаю, что добавлять какие-либо дополнительные приложения, так как несколько приложений могут привести к проблемам дальше вниз по дороге.
Давайте модифицируем Apps.py
В приложении использовать имя rbac.Core
вместо основной
:
# rbac/core/apps.py class CoreConfig(AppConfig): name = 'rbac.core'
Теперь давайте построим все для нашей первой конечной точки Получить/
Отказ Вот простой вид для приложения:
# rbac/core/views.py from django.http import HttpResponse def index(request): return HttpResponse("Hello, world. You're at the core index.")
Установите URL, чтобы указать на вид:
# rbac/core/urls.py from django.urls import path from rbac.core import views urlpatterns = [ path('', views.index) ]
Установка URL в проекте, чтобы указать на наше новое приложение:
# rbac/urls.py from django.urls import include, path urlpatterns = [ path('', include('rbac.core.urls')), ]
Проект и приложение теперь установлены. Прежде чем двигаться дальше, давайте создадим пользовательскую модель для пользователей.
Пользовательская модель пользователя
В Django всегда хорошая идея создать пользовательскую модель для пользователей. Трудно изменить модель пользователя позже, и это не так много работы, чтобы катить собственную модель. Пользовательская модель дает наибольшую гибкость позже.
Давайте сначала явно определим нашу бэкэнд аутентификации и Пользователь
Модель, которую мы хотим использовать в settings.py
:
# rbac/settings.py AUTHENTICATION_BACKENDS = ['django.contrib.auth.backends.ModelBackend'] AUTH_USER_MODEL = 'core.User'
Теперь мы создаем нашу пользовательскую модель пользователей в Models.py
Определение Пользователь
и Усманагеру
:
# rbac/core/models.py import uuid from django.db import models from django.contrib.auth.models import ( AbstractBaseUser, BaseUserManager ) class UserManager(BaseUserManager): def create_user(self, email, name, password=None): """ Create and save a user with the given email, name and password. """ if not email: raise ValueError('Users must have an email address') user = self.model( email=self.normalize_email(email), name=name ) user.set_password(password) user.save() return user class User(AbstractBaseUser): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) email = models.EmailField( verbose_name='email address', max_length=255, unique=True, ) name = models.CharField(max_length=32, blank=False, null=False) is_active = models.BooleanField(default=True) objects = UserManager() USERNAME_FIELD = 'email' REQUIRED_FIELDS = ['name'] def __str__(self): return self.email
Я не буду пытаться объяснить это подробно, как вы можете найти полный пример здесь В документации Django. Наше Пользователь
имеет поля Эл. адрес
и имя
. Поле Email
Должен быть уникальным, и мы используем это как наше имя пользователя. Мы используем UUID в качестве первичного ключа во всех моделях, которые мы создаем. Мы также создаем наших собственных Упреждающий
что мы можем использовать для создания новых пользователей как User.Objects.create_user (Email = Email ,,,)
Отказ
Теперь давайте создадим нашу первую миграцию для создания модели пользователя в базе данных:
$ python manage.py makemigrations
На данный момент вы можете настроить вашу базу данных. Мы будем использовать sqlite3.
В этой статье для простоты. Посмотреть Эта статья Как настроить Django, чтобы использовать базу данных Postgres и как настроить простую конечную точку для проверки здоровья.
Попробуйте это
Давайте запустим наш сервер:
$ python manage.py runserver
Откройте вкладку «Другой терминал» и сделайте запрос на свой сервер в http://localhost: 8000
:
$ curl http://localhost:8000 Hello, world. You're at the core index.
Создание сервисного слоя
Мы создаем сервисный слой, чтобы добавить развязку между просмотрами и моделями, как предложено В этой статье Отказ Такой развязный слой помогает хранить модели Lean и все деловую логику в одном месте. Услуги также очень полезны для тестирования, так как мы можем создавать ресурсы с услугами аналогичным образом, поскольку реальные пользователи будут делать.
Давайте создадим услуги для создания пользователей и поиск пользователей:
# rbac/core/services.py import typing from rbac.core.models import User def create_user(email: str, name: str, password: str) -> User: return User.objects.create_user(email=email, name=name, password=password) def find_user_by_email(email: str) -> typing.Optional[User]: try: return User.objects.get(email=email) except User.DoesNotExist: return None
Добавление тестов
Теперь мы можем сделать Очень важно предмет Мы знаем, что каждый разработчик должен делать и добавлять тесты для нашего проекта. Давайте сначала установим pteest
и pytest-django
:
$ printf "pytest\npytest-django\n" > requirements-dev.txt $ pip install -r requirements-dev.txt
Настроить Pytest.ini
:
# pytest.ini [pytest] DJANGO_SETTINGS_MODULE = rbac.settings
Давайте создадим простой тест для создания пользователя:
# tests/test_services.py import pytest from rbac.core.services import create_user, find_user_by_email @pytest.mark.django_db def test_create_user(): email = "test@example.com" name = "Jane Doe" password = "some-clever-password" user = create_user(email=email, name=name, password=password) assert user.email == email found_user = find_user_by_email(email=email) assert found_user == user
Теперь вы можете запустить тест и увидеть его пройти:
$ pytest
Заключение
Который завершает часть 1. В следующих частях мы будем добавлять представления и тесты для входа в систему пользователей, предотвращая ненужные пользователи, которые появляются ресурсы, и, наконец, добавляя гранулированные роли контроль доступа. Увидимся!
Оригинал: “https://dev.to/ksaaskil/setting-up-django-rest-api-with-custom-user-model-and-tests-5b8f”