Рубрики
Без рубрики

Регистрация и авторизация пользователя на API Django с Joser и JSON Web Tokens.

Первоначально опубликовано на моем сайте В первой части вступительной структуры REST Django мы настроили T … Помечено Python, Django, Tutorial, Beginters.

Первоначально опубликовано на мой веб-сайт

В первой части вступительной структуры REST Django мы настроили проект и провели обзор того, что такое проект. Проверьте это, если у вас нет.

Создание веб -API с Django

Льюис Кори ・ 6 ноября ’19 ・ 3 мин читать

Обзор

В этом разделе мы проведем регистрацию пользователей в рамках Django REST и используем веб -токены JSON для авторизации. Мы также расширим модель пользователя по умолчанию, которая поставляется с Django, чтобы позволить нам получить более подробную информацию о пользователях нашей системы.

Проект доступен на GitHub .

Что такое веб -токен JSON?

JSON WEB Token (JWT)-это интернет-стандарт для создания токенов доступа на основе JSON, которые утверждают некоторое количество претензий. Например, сервер может генерировать токен, который имеет флаг «вошел в систему как администратор» или «вошел в систему, как этот пользователь», и предоставить его клиенту. Затем клиент может использовать этот токен, чтобы доказать, что он вошел в систему как администратор. Токены подписаны частным ключом одной стороны (обычно сервером), чтобы обе стороны могли проверить, что токен является законным. Токены предназначены для компактных, URL-безопасных и пригодных для использования, особенно в контексте одного подписания веб-браузера (SSO). Утверждения JWT обычно могут использоваться для передачи идентификации аутентифицированных пользователей между поставщиком идентификаторов и поставщиком услуг. В отличие от аутентификации на основе токков, JWT не хранятся в базе данных приложения. Для более подробного объяснения того, как работают JWTS, посмотрите это удивительное видео.

Настройка проекта

Прежде чем продолжить, давайте посмотрим на некоторые из конечных точек, которые мы будем использовать в этом разделе.

/auth/users/ Зарегистрируйте нового пользователя
/auth/users/me/ Получить/обновить в данный момент в настоящее время пользователь
/auth/jwt/create/ Создайте JWT, передав действительного пользователя в запросе POST этой конечной точке
/auth/jwt/обновление/ Получите новый JWT после жизни ранее сгенерированного истекает
/API/Accounts/All-Profilile/ Получите все профили пользователей и создайте новый
/api/accounts/profile/id/ подробный вид профиля пользователя

Это может показаться горсткой, но хорошая новость заключается в том, что Джозер сделал большую часть тяжелой работы для нас. Все конечные точки, начиная с auth сгенерированы Джозером.

Возвращаясь к первой части серии, мы установили несколько пакетов Python. Нам нужно добавить эти пакеты в файл настройки проекта, чтобы использовать их в нашем проекте Django.

Не забудьте изменить настройки аутентификации для DRF, чтобы отразить использование JWT.

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ),
}

При настройке этой системы важно зарегистрировать маршруты для конечных точек, которые будут использоваться в рамках проекта. Зарегистрировав пути в основной файл проекта urls.py, мы можем получить доступ к различным конечным точкам, которые нам понадобятся позже.

Модель профиля пользователя

Django поставляется с пользовательской моделью по умолчанию с такими полями, как имя пользователя, пароли и ввод электронной почты, в некоторых случаях эти поля может недостаточно побудить нас расширить модель или создать пользовательскую модель. В этом случае мы будем расширять модель пользователя, потому что нам нужен способ дифференцировать пользователей. Там будет два типа пользователей. Те, которые могут организовать мероприятия, и те, которые просто хотят посещать мероприятия.

from django.db import models
from django.contrib.auth.models import User
# Create your models here.

class userProfile(models.Model):
    user=models.OneToOneField(User,on_delete=models.CASCADE,related_name="profile")
    description=models.TextField(blank=True,null=True)
    location=models.CharField(max_length=30,blank=True)
    date_joined=models.DateTimeField(auto_now_add=True)
    updated_on=models.DateTimeField(auto_now=True)
    is_organizer=models.BooleanField(default=False)

    def __str__(self):
        return self.user.username

Мы также создадим сигнал post_save для автоматического создания профиля пользователя для новых пользователей, которые регистрируются на платформе. Для этого создайте файл signals.py и напишите код ниже.

from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver

from .models import userProfile


@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
    if created:
        userProfile.objects.create(user=instance)

Для подробного объяснения того, как работают сигналы, это Хорошая отправная точка Не забудьте зарегистрировать сигнал в вашем файле app.py так:

from django.apps import AppConfig


class AccountsConfig(AppConfig):
    name = 'accounts'

    def ready(self):
        import accounts.signals

Сериализаторы

С базовой установкой, давайте перейдем к реализации API. Если вы новичок в Django, сериализаторы позволяют преобразовать сложные данные, такие как запросы и экземпляры модели в нативные типы данных Python, которые можно легко отображать в такие форматы, как JSON. Это называется сериализацией. Они также разрешают десериализацию после первой проверки входящих данных запроса.

В каталоге приложения мы инициируем файл serializers.py и введем код ниже:

from rest_framework import serializers
from .models import userProfile
class userProfileSerializer(serializers.ModelSerializer):
    user=serializers.StringRelatedField(read_only=True)
    class Meta:
        model=userProfile
        fields='__all__'

Пройдя линию за линию, мы сделали импорт сериализаторы Класс из REST_FRAMEWORD, а также модель, которую мы хотим сериализовать. В этом случае это модель пользователя.

Наш первый сериализатор – это пользовательский профильриализатор. Это будет наследовать от класса моделейализатора в Джанго. Как вы отмечали ранее, модель UserProfile была связана с пользовательской моделью по умолчанию в Django. Мы укажем это поле как read_only. Это означает, что поле будет включено в вывод API, но не будет включено во время операций создания или обновления в конечной точке. Чтобы заполнить это поле, мы создадим метод для автоматического заполнения поле пользователем запроса.

В REST_FRAMEWORK есть и другие типы сериализатора, такие как лисриализатор и гиперлинкедмоделериализатор. Для комплексного руководства по сериалам, Framework REST док это отличное место для начала.

API просмотры

Чтобы получить доступ к данным в API, мы используем конечные точки. Это в основном маршруты URL. Как работает Джанго, это то, что каждый URL связан с контроллером, называемым представлением. Контроллеры могут быть основаны на классе или на основе функций. После того, как маршрутизация определила, какой контроллер использовать для запроса, ваш контроллер отвечает за понимание запроса и создание соответствующего вывода.

Одной из реализации этого контроллера в рамках REST является общие виды Анкет Они были разработаны в качестве ярлыка для общих моделей использования. Они принимают определенные общие идиомы и закономерности, найденные в области развития и абстрагируют их, чтобы вы могли быстро писать общие взгляды на данные, не повторяя себя. Некоторые из этих представлений являются CreateApiview, ListApiview, ListCreateApiview, retiveupdatedErsoyapiview, и этот список можно продолжить.

Мы внедрим ListCreateApivewiew и RetiveUpdatedEStroyApiview.

from rest_framework.generics import (ListCreateAPIView,RetrieveUpdateDestroyAPIView,)
from rest_framework.permissions import IsAuthenticated
from .models import userProfile
from .permissions import IsOwnerProfileOrReadOnly
from .serializers import userProfileSerializer

# Create your views here.

class UserProfileListCreateView(ListCreateAPIView):
    queryset=userProfile.objects.all()
    serializer_class=userProfileSerializer
    permission_classes=[IsAuthenticated]

    def perform_create(self, serializer):
        user=self.request.user
        serializer.save(user=user)


class userProfileDetailView(RetrieveUpdateDestroyAPIView):
    queryset=userProfile.objects.all()
    serializer_class=userProfileSerializer
    permission_classes=[IsOwnerProfileOrReadOnly,IsAuthenticated]

Каждое представление API связано с классом Serializer, который мы ранее создали. Одна вещь, которую мы замечаем, это exector_create Метод в UserprofileListCreateView класс. Вот как мы указываем, как мы хотим создать сериализатор. В этом случае мы хотели заполнить поле пользователя read_only запрашивающим пользователем, а затем заполнить сериализатор этим значением.

Затем представления связаны с конечной точкой URL в файле приложения urls.py:

from django.urls import include, path
from rest_framework.routers import DefaultRouter

from .views import UserProfileListCreateView, userProfileDetailView

urlpatterns = [
    #gets all user profiles and create a new profile
    path("all-profiles",UserProfileListCreateView.as_view(),name="all-profiles"),
   # retrieves profile details of the currently logged in user
    path("profile/",userProfileDetailView.as_view(),name="profile"),
]

Разрешения

Разрешения определяют, должен ли запрос быть предоставлен или отказ в доступе. Django Rest Framework Ships с несколькими. Я не буду вдаваться в них, так как это Документация довольно всеобъемлющий в них. Однако давайте обратим наше внимание к IsownerProfileorReadonly Класс разрешений.

Это пользовательская реализация разрешения. Мы инициализируем файл разрешения.

from rest_framework.permissions import BasePermission,SAFE_METHODS

class IsOwnerProfileOrReadOnly(BasePermission):
    def has_object_permission(self, request, view, obj):
        if request.method in SAFE_METHODS:
            return True
        return obj.user==request.user

Переопределяя класс базовой сети, мы можем создать наше собственное разрешение. Этот класс имеет два метода, которые мы можем переопределить.

.has_permission () и .has_object_permission ()

Оба должны вернуть True, если запрос должен быть предоставлен и неверно, если запрос будет отклонен. Safe_methods получают, опции и голова.

В нашем пользовательском классе разрешений мы проверяем, похож ли запрашивающий пользователь пользователь. Это гарантирует, что владелец профиля является единственным, кто может изменить свою информацию.

API -тесты

Почти сделано сейчас 🤣. Мы напишем несколько тестов, чтобы гарантировать, что наши конечные точки работают по мере необходимости.

class userProfileTestCase(APITestCase):
    profile_list_url=reverse('all-profiles')
    def setUp(self):
        # create a new user making a post request to djoser endpoint
        self.user=self.client.post('/auth/users/',data={'username':'mario','password':'i-keep-jumping'})
        # obtain a json web token for the newly created user
        response=self.client.post('/auth/jwt/create/',data={'username':'mario','password':'i-keep-jumping'})
        self.token=response.data['access']
        self.api_authentication()

    def api_authentication(self):
        self.client.credentials(HTTP_AUTHORIZATION='Bearer '+self.token)

    # retrieve a list of all user profiles while the request user is authenticated
    def test_userprofile_list_authenticated(self):
        response=self.client.get(self.profile_list_url)
        self.assertEqual(response.status_code,status.HTTP_200_OK)

    # retrieve a list of all user profiles while the request user is unauthenticated
    def test_userprofile_list_unauthenticated(self):
        self.client.force_authenticate(user=None)
        response=self.client.get(self.profile_list_url)
        self.assertEqual(response.status_code,status.HTTP_401_UNAUTHORIZED)

    # check to retrieve the profile details of the authenticated user
    def test_userprofile_detail_retrieve(self):
        response=self.client.get(reverse('profile',kwargs={'pk':1}))
        # print(response.data)
        self.assertEqual(response.status_code,status.HTTP_200_OK)


    # populate the user profile that was automatically created using the signals
    def test_userprofile_profile(self):
        profile_data={'description':'I am a very famous game character','location':'nintendo world','is_creator':'true',}
        response=self.client.put(reverse('profile',kwargs={'pk':1}),data=profile_data)
        print(response.data)
        self.assertEqual(response.status_code,status.HTTP_200_OK)

Чтобы запустить тесты, запустите команду Python Manage.py Test в вашем терминале.

Если вы чувствуете себя немного смущенным, вот структура проекта до этого момента.

eventScheduler  
├── accounts    
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations     
│   │   └── __init__.py
│   ├── models.py      
│   ├── permissions.py 
│   ├── serializers.py 
│   ├── tests.py       
│   ├── urls.py        
│   └── views.py       
├── eventScheduler     
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-35.pyc
│   │   └── settings.cpython-35.pyc
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py

Демонстрация с почтальником

Регистрация пользователя

Получите токен доступа

Получить/обновить аутентифицированный пользователь.

Мы будем передавать запрос GET в качестве пользователя Бэтмен Анкет Для этого каждый запрос Post должен иметь JWT для идентификации пользователя как действительного пользователя. В Post Man мы можем поместить токен в раздел Auth и указать, что вы хотите использовать токен носителя. Затем вы вставьте в токен доступа, сгенерированный выше.

Получите все профили пользователей

Это будет через запрос получить.

Обновить аутентифицированный пользователя

С помощью запроса на то

Дополнительные ресурсы

  1. Официальные документы Django Rest Ramework .
  2. Joser Documenentation Анкет
  3. Курс Udemy Michele Saba

Это конец этого поста в Лунг. Я надеюсь с этой информацией Вы тоже можете сделать свой собственный API с Django. Если у вас есть какие -либо вопросы, не стесняйтесь оставить комментарий. Вы также можете связаться со мной через мой Веб -сайт или на Twitter Анкет

Оригинал: “https://dev.to/lewiskori/user-registration-and-authorization-on-a-django-api-with-djoser-and-json-web-tokens-4kc7”