Учебник по Джанго JWT
Что такое JWT
JWT (Json Web Token) — это стандарт, определяющий способ передачи защищенной информации с помощью токенов.
JWT обычно используются для аутентификации и авторизации в веб-приложениях, API-интерфейсах и архитектурах микросервисов, включая внешние приложения, созданные с использованием таких технологий, как Next.js, Angular или React. JWT предоставляют безопасные средства передачи токенов аутентификации между клиентом и сервером.
JWT могут быть подписаны публично или конфиденциально. Стандартный JWT выглядит следующим образом:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ. SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Как видите, его структура состоит из 3 частей, разделенных точкой (.), а именно:
- заголовок
- полезная нагрузка
- подпись
Заголовок:
Заголовок — это первая часть токена JWT, и он определяет алгоритм, используемый для подписи и проверки подписи. Алгоритмы подписи могут включать подпись RSA, HMAC-SHA256, HMAC-SHA512 и другие.
Полезная нагрузка:
Полезная нагрузка — это вторая часть, и она содержит претензии. Претензия может включать в себя следующее:
- Идентификатор пользователя.
- Разрешения.
- Время истечения.
- Выпущено-вовремя.
- Любые другие данные, требуемые приложением.
Подпись
Подпись и третья часть создаются путем объединения заголовка в кодировке base64, полезной нагрузки в кодировке base64 и секретного ключа. Подпись используется для проверки подлинности токена JWT.
Все три части кодируются Base64Url и объединяются с использованием точек («.») для формирования строки URL.
Когда пользователь входит на веб-сайт, он аутентифицируется, и сервер генерирует уникальный токен JWT в качестве ответа. Затем пользователь использует токен в последующих запросах, включая его в заголовок авторизации в формате Authorization: Bearer [JWT token]
.
Во время последующих запросов сервер будет постоянно проверять подлинность токена при каждом запросе.
Начиная
В этом разделе мы создадим приложение django и продемонстрируем, как генерируются токены JWT, когда пользователь аутентифицируется, и как ограничить доступ к определенным представлениям, когда пользователь не предоставляет токен.
Начнем с создания и активации новой виртуальной среды с помощью модуля venv.
python -m venv myenviron source myenviron/bin/activate
Установите django, django rest framework и простой пакет JWT. Простой JWT обеспечивает простой в использовании механизм проверки подлинности для среды Django REST.
pip install django djangorestframework djangorestframework-simplejwt
Создайте проект django с именем django_jwt
и приложение с именем tokens
.
django-admin startproject django_jwt cd django_jwt python manage.py startapp tokens
Добавьте платформу Django rest, пакет Simple JWT и приложение tokens в список INSTALLED_APPS
в файле settings.py.
INSTALLED_APPS = [ ...... 'rest_framework_simplejwt', 'rest_framework', 'tokens', ]
Затем добавьте rest_framework_simplejwt.authentication.JWTAuthentication
в файл DEFAULT_AUTHENTICATION_CLASSES
settings.py.
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework_simplejwt.authentication.JWTAuthentication', ], }
Платформа Django rest использует параметр DEFAULT_AUTHENTICATION_CLASSES
, чтобы указать список классов аутентификации для аутентификации. Добавление rest_framework_simplejwt.authentication.JWTAuthentication
configures Django Rest framework для использования JWT-аутентификации для вашего приложения.
Запустите миграцию, чтобы создать таблицы пользовательской базы данных по умолчанию. Создайте суперпользователя с именем пользователя admin
.
python manage.py migrate python manage.py createsuperuser
Логин пользователя
Когда пользователь входит в систему, мы хотим, чтобы сервер предоставил ему токен JWT, который он будет использовать для аутентификации при выполнении запросов в приложении.
В файле tokens/views.py создайте класс LoginView
, который аутентифицирует пользователя и создает уникальный токен.
from django.http import JsonResponse from rest_framework.views import APIView from rest_framework_simplejwt.tokens import RefeshToken from django.contrib.auth.models import User from django.contrib.auth import authenticate # Create your views here. class LoginView(APIView): def post(self, request): username = request.data.get('username') password = request.data.get('password') user = authenticate( username=username, password=password) refresh = RefeshToken.for_user(user) return JsonResponse( { 'refresh':str(refresh), 'access':str(refresh.access_token) } )
В приведенном выше коде мы получаем имя пользователя и пароль из данных запроса, а затем аутентифицируем пользователя с помощью встроенного метода аутентификации.
authenticate()
method — это встроенная функция, предоставляемая инфраструктурой аутентификации Django. Он проверяет учетные данные пользователя и аутентифицирует их.
Refresh.for_user(user)
— создает токен для пользователя
Наконец, мы возвращаем JsonResponse с обновлением и access_token в виде строк.
Откройте файл root urls.py
и сопоставьте LoginView
с URL-адресом.
path('api/login', LoginView.as_view(), name ='login')
Мы будем использовать учетные данные суперпользователя и инструмент POSTMAN для проверки конечной точки входа. Если у вас нет POSTMAN, вы можете найти скачать его здесь.
Откройте Postman и выполните запрос на получение конечной точки http://127.0.0.1:8000/api/login. Тип контента должен быть установлен на application/json
.
Как вы можете видеть выше, URL-адрес входа возвращает обновление и токен доступа.
refresh
: как следует из названия, токен обновления используется для обновления токенов; Проще говоря, он используется для получения нового токена доступа без входа в систему. Токен обновления имеет более длительный срок действия по сравнению с токеном доступа.
Пользователь может использовать токен обновления, чтобы запросить новый токен доступа, если срок действия токена доступа истек.
Токены обновления имеют более длительный срок действия.
access
: для предоставления доступа используется токен доступа. Пользователь будет использовать токен доступа для аутентификации и авторизации запросов приложений. Токены доступа имеют короткий срок действия.
Если мы расшифруем токен доступа, он даст вам следующее
{ typ: "JWT", alg: "HS256" }. { token_type: "access", exp: 1686203362, iat: 1686203062, jti: "7ca1b5721c7145feab6b1efe0f127008", user_id: 1 }. [signature]
Заголовок:
typ: “JWT”
: указывает, что токен является JWT.alg: “HS256” :
указывает, что для подписи маркера используется алгоритм HMAC-SHA256.
Полезная нагрузка:
token_type: “access”
: указывает, что это токен доступа.exp: 1686203362
: указывает отметку времени истечения срока действия токена; метка времени представлена как метка времени Unix.iat: 1686203062
: представляет отметку времени выдачи токена.jti: “7ca1b5721c7145feab6b1efe0f127008”
: уникальный идентификатор токена.user_id: 1
— идентификатор пользовательского объекта, связанного с токеном. В нашем случае это суперпользователь, а django присвоил id =1
>>> from django.contrib.auth.models import User >>> user = User.objects.get(username="admin") >>> user.id 1 >>>
Подпись:
[signature]
— указывает подпись JWT,
Давайте создадим защищенное представление и используем токены для авторизации пользователя. Откройте views.py и добавьте следующий код.
from rest_framework.permissions import IsAuthenticated class RestrictedView(APIView): permission_classes = [IsAuthenticated] def get(self, request, format=None): # Your code here return JsonResponse({"response":"YOU ARE ALLOWED HERE"})
Затем сопоставьте представление с URL-адресом.
path('api/restricted', RestrictedView.as_view(), name ='restricted')
Выполните GET-запрос к конечной точке http://127.0.0.1:8000/api/restricted с помощью Postman.
Как видите, он возвращает следующий ответ, так как мы не предоставили токен доступа в заголовке.
{ "detail": "Authentication credentials were not provided." }
Добавьте токен доступа в заголовки и снова выполните запрос GET. В параметрах авторизации выберите Bearer Token
и добавьте токен доступа в отведенное место.
Как видите, мы получили ожидаемый ответ.
Если вы укажете неправильный или просроченный токен доступа, вы получите эту ошибку:
{ "detail": "Given token not valid for any token type", "code": "token_not_valid", "messages": [ { "token_class": "AccessToken", "token_type": "access", "message": "Token is invalid or expired" } ] }
Заключение
В этом руководстве вы познакомились с веб-токенами JSON (JWT), их структурой, их работой за кулисами и тем, как использовать библиотеку Simple JWT в приложении Django. Мы узнали об их значении в процессах аутентификации и авторизации.
Используя JWT с Django Rest Framework, вы можете повысить безопасность своих конечных точек API.
Дополнительные материалы на PlainEnglish.io.
Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter, LinkedIn, YouTube и Discord .