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

Django Rest Framework tokenauthentication

Эта статья предполагает, что вы знакомы с Джанго и основы веб -сайта Django Rest Framework … Tagged с Python, начинающими, Django, программированием.

Эта статья предполагает, что вы знакомы с Django и основы Django Rest Framework Веб -фреймворк.

Реализация аутентификации токена в структуре REST не совсем проста. После просмотра документов и сканирования по сообщениям в блоге я нашел «простой» способ реализации Tokenauthentication схема.

Прежде чем углубляться, лучше всего немного объяснить, что такое структура Rest Django, и некоторые из его важных концепций.

Django Rest Framework (DRF).

Django Rest Framework Является ли рамка Python для развязки и “API-P-первой” веб приложение. Это позволяет вам преобразовать ваши существующие модели Django в форматирование, которое переводится на и обратно Json .

Как следует из названия, DRF строится на вершине Django Framework. Фактически, он был построен, чтобы позволить API REST Building REST с использованием структуры Django.

Ключевые понятия DRF

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

«Serializer» в DRF позволяет сериализовать и десериализовать экземпляры модели Django в различное представление, такое как JSON. Это делается путем создания serializer.py Файл в желаемом каталоге, за которым следует соответствующий код, ответственный за выполнение сериализации.

Вид

Так же, как у Джанго есть views.py Файл отвечает за создание логики и представление данных клиенту в разных формах. DRF строится на вершине этой идеи и предоставляет свои собственные представления для представления данных. Это два способа представлять представления в DRF: функциональные представления и взгляды на основе классов.

В этом посте я буду использовать взгляды на основе классов, которые будут наследовать от Framework’s Framework Apiview Анкет

Почему Apiview ?

  • Это оптимизируется для согласования контента и установления правильного визуализатора для ответа.
  • Он ловит все Apiexception Исключения и возвращает соответствующие ответы.
  • Входящие запросы проверены, и перед отправкой запроса будет выполнена соответствующие разрешения и/или проверки дроссельной заслонки.

ПРИМЕЧАНИЕ

Некоторые разработчики предпочитают назвать Просмотры Файл api.py Анкет Это должно быть отделено от Джанго views.py файл.

Запросы и ответы

Структура REST обеспечивает Ответ Объект, который расширяет Джанго Httprequest Анкет Расширение позволяет ему предоставить надежный способ разбора запросов. Ответ Объект обеспечивает request.data Атрибут, который похож на Django View’s запрос. ПОЧТА Но это больше подходит для создания веб -API.

Маршрутинг

Структура REST имеет маршрутизатор Модуль для маршрутизации URL API в Джанго. Это обеспечивает последовательный способ написания логики представления для набора URL -адресов. Чтобы создать маршруты для URL -адресов, вы создаете router.py Файл в желаемом каталоге, а затем включают Это в Django urlconf (конфигурация URL).

Реализация в этом посте будет не использовать маршрутизатор REST Framework, а Django urlconf.

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

Это схема аутентификации HTTP, которая использует токен в качестве средства для проверки и предоставления доступа клиентам. Только клиенты с действительным токеном предоставлены доступом. Токен передается как полезная нагрузка на http Авторизация Заголовок для каждого запроса. Сервер получает токен и проверяет его с тем, что он хранил. Если токены совпадают, то клиент проверяется и предоставляется доступ.

Установка и конфигурация

Чтобы настроить изолированную среду, вы используете виртуальную среду.

Установка Django & DRF

Если виртуальная среда настроена и активирована, запустите PIP установить Django Djang-Restframework в терминале для установки Django и DRF.

Чтобы начать проект, запустите Python django-admin startProject [имя проекта] Чтобы начать новый проект. Я буду называть мою аутентификация .

Установленные приложения

Джанго должен распознать и использовать структуру REST и схему аутентификации токена. Добавьте их в список установленных приложений в настройки.py файл.

# Application definition

INSTALLED_APPS = [
    ...
    "rest_framework",
    "rest_framework.authtoken"
    ...

]

Установка класса аутентификации и разрешения.

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

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": [
        "rest_framework.authentication.TokenAuthentication",
    ],
    "DEFAULT_PERMISSION_CLASSES": [
        "rest_framework.permissions.AllowAny",
    ]
}

Миграция.

Чтобы применить изменения, которые требуют интеграции базы данных (Django поставляется с по умолчанию sqlite ), они должны быть мигрировал Анкет Запустить Python Manage.py Migrate Чтобы применить такие изменения.

Tokenauthentication.

Tokenauthentication отличается от Sessonauthentication. На сервере при использовании схемы аутентификации токена не создано ни одного состояния. Только обоснованность токена проверяется. Если есть совпадение, пользователю предоставляется доступ, или, более определенно, аутентифицируется.

Создать пользователя.

Учетная запись пользователя необходима для проверки реализаций. Джанго Manage.py Командная утилита может использоваться для создания учетной записи Super User.

python manage.py createsuperuser --username johndoe --email johndoe@gmail.com

Тестовый вид

Давайте создадим представление с разрешением, установленным только для аутентифицированных пользователей. Запросы, отправленные на представление с неверным токеном, не будут предоставлены. Вид будет обрабатывать Получить Запросить, чтобы вернуть сообщение Привет, мир! для действительных токенов.

# views.py

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated 

class HelloView(APIView):
    permissions_classes = [IsAuthenticated] # <-------- Only authenticated users can access this view

    def get(self, request):
        context = {"message": "Hello, World!"} # <------ Response to the client
        return Response(context)

Добавьте шаблон URL и просмотр в файл urlConf, urls.py

# urls.py
 from django.urlsconf import path
 from authentication.views import HelloView

urls_patterns = [
    path("/api-token-auth", HelloView.as_view())
]

Давайте проверим представление. Запрос без токена будет отправлен.

Python имеет легкий клиент HTTP под названием httpie Анкет Установите его и следуйте.

..authentication> http http://localhost:8000/api-is-authenticated
HTTP/1.1 401 Unauthorized
Allow: GET, HEAD, OPTIONS
...
Content-Type: application/json
...
WWW-Authenticate: Token # <----------- Take note of this
...
{
    "detail": "Authentication credentials were not provided."
}

Из вышесказанного запрос не был аутентифицирован, потому что с запросом не было связано ни один [допустимый] токен. Кроме того, если вы осмотрите заголовок, вы заметите www-authentication: токен полезная нагрузка. То есть сказать клиенту, что токен необходим для доступа к данным на http://localhost: 8000/api-token-auth URL Позже мы снова протестируем представление, но с действительным токеном.

Регистрация

Аутентификация регистрации отвечает за работу регистрации и создание учетной записи пользователя. Запрос JSON от клиента содержит учетные данные, необходимые для создания учетной записи. Если учетные данные действительны, учетная запись будет создана.

Чтобы проверить, действительны ли данные, он должен перепроверить с сериализованными данными модели.

Создать serializers.py Задайте и напишите следующий код:

# serializers.py

from django.contrib.auth.models import User

from rest_framework import serializers


class RegistrationSerializer(serializers.ModelSerializer):
     class Meta:
        model = User
        fields = [
            "id", 
            "username", 
            "first_name", 
            "last_name", 
            "email", 
            "password", 
            "is_active", 
            "is_staff"
        ]
        extra_kwargs = {"id": {"read_only": True}, "password": {"write_only": True}}
        read_only_fields

    def create(self, validated_data):

        username = validated_data["username"]
        first_name = validated_data["first_name"]
        last_name = validated_data["last_name"]
        email = validated_data["email"]
        password = validated_data["password"]

        user = User.objects.create_user(
            username=username,
            first_name=first_name,
            last_name=last_name,
            email=email,
            password=password,
        )

        return user

Для кода просмотра для обработки логики для входящего запроса. Запрос будет Пост запрос.

Представление передаст входящие данные в Registrationserializer класс для проверки и создания пользователя. Сериализатор вернет объект, который сообщает, являются ли данные действительными или нет. Представление будет проверять, действительны ли данные. Если действителен, это сохранит его, генерирует токен и возвращайте ответ. Если не действителен, он вернет ответ ошибки.

# views.py

from django.contrib.auth.models import User

from authentication.serializers import RegistrationSerializer

from rest_framework import serializers
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.authtoken.models import Token
from rest_framework import permissions

class RegistrationView(APIView):
     """Registeration View"""

    def post(self, request, *args, **kwargs):
        """Handles post request logic"""
        registration_serializer  = RegistrationSerializer(data=request.data)

        # Generate tokens for existing users
        for user in User.objects.all():
            if not user:
                break
            else:
                try:
                    Token.objects.get(user_id=user.id)
                except Token.DoesNotExist:
                    Token.objects.create(user=user)

        if registration_class.is_valid():
            user = registration_serializer.save()
            token = Token.objects.create(user=user)

            return Response(
                {
                    "user": {
                        "id": serializer.data["id"],
                        "first_name": serializer.data["first_name"],
                        "last_name": serializer.data["last_name"],
                        "username": serializer.data["username"],
                        "email": serializer.data["email"],
                        "is_active": serializer.data["is_active"],
                        "is_staff": serializer.data["is_staff"],
                    },
                    "status": {
                        "message": "User created",
                        "code": f"{status.HTTP_200_OK} OK",
                    },
                    "token": token.key,
                }
            )
        return Response(
             {
                "error": serializer.errors,
                "status": f"{status.HTTP_203_NON_AUTHORITATIVE_INFORMATION} \ 
                    NON AUTHORITATIVE INFORMATION",
            }
        )

Затем создайте шаблон URL и добавьте представление, ответственное за запрос на обработку URL.

# urls.py from django.urlsconf import path from authentication.views import RegistrationViewurls_patterns = [    #...    path("/api-register-auth", RegistrationView.as_view())]

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

http --json POST http://localhost:8000/api/auth/register username="JamesChe" email="jamesuche@gmail.com" first_name="james" last_name="uche" password="jamesuche123456"{    "status": {        "code": "200 OK",        "message": "User created"    },    "token": "b4784f96c3c65387bc8ea6463d5d4658cb32b0ac",    "user": {        "id": 2,        "first_name": "james",        "last_name": "uche",        "username": "JamesChe",        "email": "jamesuche@gmail.com",        "is_active": true,        "is_staff" true,    }}

Авторизоваться

Реализация аутентификации входа в систему с использованием Framework REST довольно проста. Есть два способа достижения настройки представления входа в систему: использование встроенного представления или пользовательского представления.

Используя представление eaft_auth_token.

Framework REST обеспечивает встроенный eave_auth_token Просмотр для создания и получения токенов для аутентифицированного пользователя.

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

В urls.py Файл, импорт следующим образом: от rest_framework.authtoken.views import eave_auth_token Затем добавьте представление в UrlConf.

# urls.pyfrom rest_framework.authtoken.views import obtain_auth_tokenurl_patterns + [    path("/api-token-auth", obtain_auth_token.as_views())]

ПРИМЕЧАНИЕ:

Наименование шаблона URL может быть тем, что вы хотите.

Чтобы получить токен, клиент должен отправить запрос на URL. Клиент должен предоставить имя пользователя и пароль зарегистрированного пользователя.

..authentication> http post http//localhost:800/api-token-auth/ username="johndoe" password=123456HTTP/1.1 200 OKAllow: OPTION, POSTSContent-Type: application/json......{  "token": "bad492c010451bcba6acf7437706b8dd30eb11d5"}

Помните более ранние Helloview Посмотреть? Давайте проверим это, отправив Получить Запрос на свой URL, на этот раз с токеном, который мы только что получили.

..authentication> http http://localhost:8000/api-hello "Authorization: Token bad492c010451bcba6acf7437706b8dd30eb11d5"HTTP/1.1 200 OKAllow: GET, HEAD, OPTIONS.........{    "message": "Hello, World!" # <------------ Message because user token is valid.}

И там! Теперь мы можем получить доступ к представлению без ограничений. ожидаемый Привет, мир! Сообщение возвращается, а не ограничение.

Используя пользовательское представление

Некоторые случаи требуют, чтобы дополнительные данные об аутентифицированном пользователе отправлялись в качестве ответа на клиента. Эти «дополнительные» данные могут быть в базе данных. Чтобы получить такие данные, A сериализатор необходимо для преобразования их в формат нативного кода Python для легкой сериализации. Представление будет обрабатывать необходимую связанную логику и отправлять ответ клиенту.

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

# Serializers.pyfrom django.contrib.auth.models import Userfrom rest_framework import serializersclass UserLoginSerializer(serializers.Serializer):    """Login serializer"""        username = serializers.CharField(required=True)    password = serializers.CharField(required=True, read_only=True)class UserLoginResponse(serializers.ModelSerializer):    """Response serializer"""        class Meta:        model = User        fields = "id, username, first_name, last_name, email, password, is_active, is_staff"        read_only_fields = ["id", "password", "is_active", "is_staff"]

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

# views.pyfrom django.contrib.auth.models import Userfrom authentication.serializers import LoginSerializerfrom authentication.serializers import LoginResponseSerializerfrom rest_framework import serializersfrom rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework import statusfrom rest_framework.authtoken.models import Tokenfrom rest_framework import permissionsfrom django.contrib.auth import authenticateclass LoginView(APIView):    """Login View"""        permissions_classes = [permissions.isAuthenticated]        def post(self, request, *args, **kwargs):        login_serializer = LoginSerializer(data=request.data)                if login_serializer.is_valid():            user = authenticate(request, **serializer.data)                        if user is not None:                response_class = LoginResponseSerializer(user)                token, created_token = Token.objects.get_or_create(user_id=user.id)                                if isinstance(created_token, Token):                    token = created_token.key                                return Response(                    {                        "user": response_serializer.data,                        "status": {                            "message": "User Authenticated",                            "code": f"{status.HTTP_200_OK} OK",                        },                        "token": token.key,                    }                )            else:                raise serializers.ValidationError(                {                    "error": {                        "message": "Invalid Username or Password. Please try again",                        "status": f"{status.HTTP_400_BAD_REQUEST} BAD REQUEST",                    }                }            )                return(            {                "error": serializer.errors,                "status": f"{status.HTTP_403_FORBIDDEN} FORBIDDEN"            }        )

Создайте шаблон URL и добавьте представление в файл urlConf.

# urls.pyfrom django.urls import pathfrom authentication.views import LoginViewurlpatterns = [    #...    #...    path("/api-login-auth", views.LoginView),]

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

..authentication> http --json post http//localhost:800/api-login-auth username="johndoe" password=123456HTTP/1.1 200 OKAllow: OPTION, POSTS...Content-Type: application/json......{    "status": {        "code": "200 OK",        "message": "User Authenticated"    },    "token": "bad492c010451bcba6acf7437706b8dd30eb11d5",    "user": {        "email": "johndoe@gmail.com",        "first_name": "",        "id": 1,        "is_active": true,        "is_staff": true,        "last_name": "",        "username": "johndoe"    }}

Вывод

Реализация Tokenauthentication в Django Rest Framework может быть крутой. Но это начинает иметь смысл, когда вы понимаете концепцию: скорее наличие сеанса на сервере, вместо этого создается токен и используется для проверки пользователя по каждому запросу.

Я рекомендую использовать структуру REST Apiview Классы баз для легкой работы. Только когда продолжайте повторять себя, если вы займете в другие классы, чтобы уменьшить повторение.

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

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

Я буду признателен за ваши отзывы об этом посте. Ваше здоровье!

Оригинал: “https://dev.to/romeopeter/django-rest-framework-tokenauthentication-1544”