How to Create a JSON Web Token in the Django Rest Framework

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

Одним из наиболее распространенных и надежных способов аутентификации в современных веб-приложениях является использование JWT, сокращенного от JSON Web Tokens.

Если вы работаете с фреймворком Django Rest Framework (DRF), вы, возможно, уже знаете, что он поставляется с множеством полезных инструментов для создания API.

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

В этом руководстве я подробно расскажу вам, как создавать и использовать JWTS в фреймворке Django Rest шаг за шагом.

Содержание:

  1. Что такое JWT?

  2. Зачем использовать JWT в фреймворке Django Rest?

  3. Как настроить JWT в фреймворке Django Rest

  4. Как использовать эти токены

  5. Часто задаваемые вопросы

  6. Лучшие практики

  7. Заключительные мысли

Что такое JWT?

Веб-токен JWT (JSON) - это компактный, автономный способ безопасной передачи информации между двумя сторонами. Он часто используется для аутентификации.

Когда пользователь входит в систему, он получает токен. Этот токен сохраняется во внешнем интерфейсе (например, в localStorage), и каждый раз, когда пользователь делает запрос, он отправляется вместе с ним.

Сервер проверяет этот токен и, если все в порядке, предоставляет доступ к запрошенным данным. Нет необходимости в файлах cookie или сеансах.

JWT состоит из трех частей:

  1. Заголовок – содержит тип токена и алгоритм подписи.

  2. Полезная нагрузка – содержит данные (например, идентификатор пользователя).

  3. Подпись – используется для подтверждения того, что токен не был изменен.

Зачем использовать JWT в фреймворке Django Rest?

Вот почему JWT является отличным выбором для приложений DRF:

  • Без сохранения состояния: На сервере не требуется никаких сеансов.

  • Масштабируемость: Поскольку он не имеет состояния, он хорошо работает с более крупными приложениями и микросервисами.

  • Широко используется: JWT является общим стандартом. Многие интерфейсные фреймворки (такие как React, Vue и так далее) уже знают, как с этим работать.

Как настроить JWT в фреймворке Django Rest

Давайте разберемся с этим. Вот как настроить аутентификацию JWT в DRF.

Шаг 1: Установите необходимые пакеты

Вам понадобится библиотека для работы с JWTS. Самая популярная из них - djangorestframework-simplejwt.

Запустите это в своем терминале:

pip install djangorestframework-simplejwt

Здесь установлено все необходимое для создания, обновления и проверки веб-токенов JSON в вашем проекте DRF.

Шаг 2: Обновите настройки Django

Перейдите к своему settings.py и обновите часть REST_FRAMEWORK следующим образом:

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

Это указывает DRF искать JWT в заголовке запроса Authorization и использовать его для аутентификации пользователя. Он заменяет аутентификацию на основе сеанса, типичную для веб-приложений, аутентификацией на основе токенов, идеально подходящей для API.

Шаг 3: Добавьте URL-адреса токенов в свой urls.py

JWT работает путем выпуска пары токенов: токена access (недолговечного) и токена refresh (долгоживущего). Управление этими токенами осуществляется с помощью двух основных представлений.

В вашем urls.py ( обычно в корневом проекте или api приложении):

from django.urls import path
from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView,
)

urlpatterns = [
    path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]

В этом коде:

  • /api/token/: Клиенты (например, интерфейсные приложения или мобильные приложения) отправляют учетные данные пользователя на эту конечную точку, чтобы получить доступ и обновить токены.

  • /api/token/refresh/: Когда срок действия токена доступа истекает, клиент отправляет сюда токен обновления, чтобы получить новый токен доступа.

Шаг 4: Протестируйте его

Допустим, у вас есть пользователь с именем пользователя и паролем.

Вы можете отправить запрос POST по адресу /api/token/:

{
  "username": "your_username",
  "password": "your_password"
}

Если учетные данные указаны верно, вы получите в ответ что-то вроде:

{
  "refresh": "long_refresh_token",
  "access": "short_lived_access_token"
}

Вы будете использовать токен access для выполнения аутентифицированных запросов. Когда срок его действия истечет, отправьте токен refresh по адресу /api/token/refresh/, чтобы получить новый.

Как использовать эти токены

Включите токен доступа в Authorization заголовок ваших запросов API следующим образом:

Authorization: Bearer your_access_token_here

Когда срок действия токена доступа истечет, отправьте токен обновления на адрес /api/token/refresh/ следующим образом:

{
  "refresh": "your_refresh_token_here"
}

И вы получите новый токен доступа.

Защита ваших представлений API

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

Вот пример:

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

class SecureView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        return Response({"message": "You are authenticated!"})

Это представление вернет ответ только в том случае, если запрос содержит допустимый JWT. Если токен отсутствует или он недействителен/срок его действия истек, пользователь получает сообщение об ошибке 401 Unauthorized error.

Краткое описание

Вот что мы только что сделали:

  • Установлен и настроен simplejwt для DRF.

  • Настройте генерацию токенов и обновите конечные точки.

  • Защищенные представления с аутентификацией на основе токенов.

  • Объяснено, как создавать и обновлять запросы на основе токенов.

JWT - это мощный и масштабируемый способ защиты ваших API-интерфейсов Django. Он идеально подходит для современных веб- и мобильных приложений.

Хотите получить дополнительный шаг для настройки полезной нагрузки токенов (например, добавление ролей пользователей или электронной почты в JWT)? Дайте мне знать!

Часто задаваемые вопросы

Как долго действует токен?

По умолчанию токен доступа действует 5 минут, а токен обновления - 1 день. Вы можете настроить это в своих настройках:

from datetime import timedelta

SIMPLE_JWT = {
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=15),
    'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
}

Что это значит:

  • Это определяет, как долго будут храниться ваши токены JWT:

    • ACCESS_TOKEN_LIFETIME: Как долго действителен токен доступа (например, 15 минут).

    • REFRESH_TOKEN_LIFETIME: Как долго действителен токен обновления (например, 1 день).

Почему это важно:

  • Токен доступа - это то, что позволяет пользователю взаимодействовать с защищенными конечными точками.

  • Токен обновления используется для получения нового токена доступа без повторного входа в систему

Где я должен хранить токен во внешнем интерфейсе?

В идеале в localStorage или sessionStorage. Просто помните о рисках XSS. Не храните конфиденциальные данные в самом токене.

Вы можете сохранить токены доступа/обновления JWT во внешнем интерфейсе в виде:

  • localStorage: Данные сохраняются даже после закрытия вкладки/браузера.

  • sessionStorage: Данные теряются при закрытии вкладки/браузера.

  • Не храните конфиденциальные пользовательские данные в токене или в хранилище.

  • Токены, хранящиеся в localStorage, могут быть уязвимы для XSS-атак.

  • Если возможно, рассмотрите возможность использования файлов cookie HttpOnly для повышения безопасности (хотя и более сложных в настройке).

Могу ли я добавить пользовательские поля в токен?

Да! Вы можете переопределить TokenObtainPairSerializer, чтобы включить пользовательские данные в полезную нагрузку, например:

from rest_framework_simplejwt.serializers import TokenObtainPairSerializer

class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
    @classmethod
    def get_token(cls, user):
        token = super().get_token(user)
        token['username'] = user.username
        return token

Затем подключите его к своему urls.py.

  • Вы настраиваете полезную нагрузку JWT, чтобы включить дополнительную информацию о пользователе (например username).

  • Это означает, что когда пользователь входит в систему, JWT теперь будет содержать username внутри полезной нагрузки.

  • Это полезно, если ваш интерфейс хочет отображать имя пользователя без выполнения другого вызова API.

Краткое описание:

Section Purpose
SIMPLE_JWT settings Controls token expiration
localStorage/sessionStorage Where to store tokens on frontend
Custom Token Serializer Add extra user info to the token (e.g., username)
urls.py config Connects your custom token view to the login endpoint

Лучшие практики

Давайте теперь рассмотрим некоторые рекомендации DRF, чтобы вы могли эффективно использовать этот фреймворк:

1. Всегда используйте HTTPS

Протокол HTTPS шифрует данные, передаваемые между клиентом (браузером или приложением) и сервером. Если вместо этого вы используете HTTP, любой пользователь в той же сети (например, общедоступной Wi-Fi) может перехватить конфиденциальные данные, включая токены доступа, с помощью метода, называемого атаками типа "человек посередине" (MITM).

Рекомендации:

  • Используйте SSL-сертификат, чтобы включить HTTPS для всех конечных точек.

  • Перенаправляйте все HTTP-запросы на HTTPS.

  • Используйте заголовки HSTS (HTTP Strict Transport Security) для обеспечения соблюдения протокола HTTPS на стороне клиента.

2. Не храните конфиденциальные данные в токене

Токены, подобные JWTs, часто хранятся на стороне клиента (в localStorage, sessionStorage или файлах cookie).

Если они содержат конфиденциальные данные (например, пароли, личную информацию или секретные ключи), они представляют серьезную угрозу безопасности, особенно в случае кражи или компрометации.

Что делать вместо этого:

  • Сохраняйте только минимальную необходимую информацию (например, идентификатор пользователя или роль).

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

  • Надежно храните конфиденциальные данные на сервере, а не в токене.

3. Храните Свой ключ подписи в секрете

Что такое ключ подписи?

В системах, использующих JWTS, для подписи токена используется ключ подписи (или секретный ключ) – криптографический способ гарантировать, что токен не был подделан.

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

Рекомендации:

  • Храните свой ключ в защищенных средах (например, в переменных среды, секретных менеджерах).

  • Никогда не передавайте ключ в систему управления версиями.

  • Используйте надежные, случайно сгенерированные секреты.

  • Рассмотрите возможность использования асимметричных ключей (пар открытых и закрытых ключей) для повышения масштабируемости и безопасности (например, с помощью алгоритма RS256).

4. При Необходимости меняйте местами Токены

Что такое ротация токенов?

Ротация токенов - это процесс периодической генерации новых токенов и аннулирования старых.

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

Рекомендации:

  • Используйте токены доступа с коротким сроком службы и токены обновления с более длительным сроком службы.

  • Аннулируйте токены обновления после их использования (практика называется “ротация токенов обновления”).

  • Отслеживайте выданные токены обновления на стороне сервера, чтобы обнаружить повторное использование или кражу.

5. Установите короткий срок службы токенов доступа и разумно используйте токены обновления

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

Рекомендации:

  • Установите быстрый срок действия токенов доступа (обычно 5-15 минут).

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

  • Надежно храните токены обновления (предпочитайте файлы cookie только для HTTP).

  • Отзывать токены обновления при выходе из системы, подозрительной активности или смене устройства.

Заключительные мысли

  • Токены доступа должны быть недолговечными и ограниченными по объему.

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

  • Всегда надежно храните секреты, обслуживайте по протоколу HTTPS и не доверяйте клиенту конфиденциальную логику или данные.

Хотите, я покажу, как все это связано друг с другом в виде примера (например, как работает вход в систему, выдача токена и обновление)?

JWTS упрощают аутентификацию и делают ее более масштабируемой для API. Как только вы настроите ее на платформе Django Rest, она просто заработает – и у вас будет безопасный способ впускать пользователей и предотвращать нежелательный трафик.

Это необходимо знать, если вы создаете API-интерфейсы с помощью Django.

Дополнительная информация и ресурсы

Вернуться на верх