Как вернуть пользовательские данные с помощью маркеров доступа и обновления, чтобы идентифицировать пользователей в Django Rest Framework simple JWT?
В Django суперпользователь может добавить больше пользователей в соответствии с их списком. Я использую простой JWT с DRF для аутентификации. Но определить тип пользователя невозможно, только увидев токены доступа и обновления.
Вот мой файл settings.py
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAuthenticated',),
'DEFAULT_AUTHENTICATION_CLASSES': ('rest_framework_simplejwt.authentication.JWTAuthentication',),
}
urls.py
from django.contrib import admin
from django.urls import path, include
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('Manage_Merchants.urls')),
path('api-auth', include('rest_framework.urls')),
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]
когда я нажимаю 127.0.0.1:8000/api/token/ через Почтальон, он запрашивает имя пользователя и пароль. Когда я ставлю имя пользователя и пароль, он генерирует маркер обновления и доступа. Генерация JWT с DRF с использованием Почтальона
Так как же определить, что токен сгенерирован для суперпользователя или другого пользователя, созданного суперпользователем? Как я могу передать больше значения в виде словаря вместе с токенами доступа и обновления, чтобы определить тип пользователя?
5 ответов
В версии djangorestframework-simplejwt==4.4.0
это метод validate
вместо того to_representation
, имея в виду:
В вашем serializer.py
вам нужно переопределить TokenObtainPairSerializer
чтобы включить все данные, которые вы хотите отправить в ответ
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
def validate(self, attrs):
# The default result (access/refresh tokens)
data = super(CustomTokenObtainPairSerializer, self).validate(attrs)
# Custom data you want to include
data.update({'user': self.user.username})
data.update({'id': self.user.id})
# and everything else you want to send in the response
return data
Теперь в твоем views.py
вам необходимо переопределить TokenObtainPairView, чтобы связать его с новым сериализатором.
from .serializers import CustomTokenObtainPairSerializer
class CustomTokenObtainPairView(TokenObtainPairView):
# Replace the serializer with your custom
serializer_class = CustomTokenObtainPairSerializer
Теперь нарисуйте это в своем url.py
from rest_framework_simplejwt.views import TokenRefreshView, TokenVerifyView
from . import views
urlpatterns = [
# This one now has the custom view mapped with the custom serializer that includes the desired data
path('token/', views.CustomTokenObtainPairView.as_view(), name='token_obtain_pair'),
path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
path('token/verify/', TokenVerifyView.as_view(), name='token_verify')
]
Как сказал Кумар, вы должны переопределить TokenObtainPairView. Позвольте мне углубиться в это:
Создайте новый classView в вашем основном приложении views.py или, если вы хотите иметь более чистый код, вы можете создать новое приложение, например, с именем jwt_token_patched и создать в нем файл views.py. Теперь добавьте код ниже:
class TokenObtainPairPatchedView(TokenObtainPairView):
"""
Takes a set of user credentials and returns an access and refresh JSON web
token pair to prove the authentication of those credentials.
"""
serializer_class = serializers.TokenObtainPairPatchedSerializer
token_obtain_pair = TokenObtainPairView.as_view()
Теперь для сериализатора добавьте это:
class TokenObtainPairPatchedSerializer(TokenObtainPairSerializer):
def to_representation(self, instance):
r = super(TokenObtainPairPatchedSerializer, self).to_representation(instance)
r.update({'user': self.user.username})
return r
Метод to_representation() вызывается, когда сериализатор возвращает данные в формате json, так что вы можете добавить туда все, что захотите. помните, я просто добавил имя пользователя в значение поля пользователя, вы можете добавить любое значение элемента пользователя, которое вы хотите в нем.
Также создайте URL для этого и теперь используйте этот метод для получения токена. Не стесняйтесь задавать любые вопросы, если хотите. надеюсь, что это было полезно:)
Для настройки токена обновления лучше всего переопределить «TokenRefreshSerializer», показанный ниже. Однако, если вы хотите получить какое-либо поле из модели, нам нужно декодировать токен, чтобы получить UUID пользователя. Это можно сделать с помощью token_backend
Примечание: убедитесь, что вы используете «rest_framework_simplejwt», а не «djangorestframework-jwt», поскольку он устарел.
from rest_framework_simplejwt.serializers import TokenRefreshSerializer
from rest_framework_simplejwt.state import token_backend
class CustomTokenRefreshSerializer(TokenRefreshSerializer):
def validate(self, attrs):
data = super(CustomTokenRefreshSerializer, self).validate(attrs)
decoded_payload = token_backend.decode(data['access'], verify=True)
user_uid=decoded_payload['user_id']
# add filter query
data.update({'custom_field': 'custom_data')})
return data
А затем используйте этот сериализатор, как показано ниже, с «CustomTokenRefreshView», который наследует «TokenRefreshView».
from rest_framework_simplejwt.views import TokenRefreshView
class CustomTokenRefreshView(TokenRefreshView):
"""
Custom Refresh token View
"""
serializer_class = CustomTokenRefreshSerializer
И добавьте это в URL
path('api/token/refresh/', CustomTokenRefreshView.as_view(), name='token_refresh'),
Да, вы можете сделать это, вы можете переопределить TokenObtainPairView и переопределить метод post.
Чтобы добавить пользовательские данные из вашей пользовательской модели в токен доступа при использовании TokenObtainPairSerializer rest_framework_simplejwt , вы можете создать собственный сериализатор, который наследуется от TokenObtainPairSerializer, и переопределить его метод проверки, чтобы включить пользовательские данные в полезную нагрузку токена.
Вот пример того, как вы можете это сделать:
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework import serializers
class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
def validate(self, attrs):
data = super().validate(attrs)
# Add custom data from your user model here
user = self.user
data['user_id'] = user.id
data['user_username'] = user.username
# Add more custom data fields as needed
return data
В этом примере мы создали собственный сериализатор под названием CustomTokenObtainPairSerializer, который наследуется от TokenObtainPairSerializer . Мы переопределяем метод validate, который отвечает за проверку учетных данных пользователя и создание токена, чтобы включить в ответ пользовательские данные.
При необходимости вы можете добавить в словарь данных любые пользовательские данные из вашей пользовательской модели. В этом примере мы добавили идентификатор и имя пользователя, но при необходимости вы можете включить дополнительные настраиваемые поля данных.
Затем вы можете использовать собственный сериализатор в представлениях аутентификации. Например, в ваших представлениях или наборах представлений, где вы хотите получить токен, вы можете указать свой собственный сериализатор:
from rest_framework_simplejwt.views import TokenObtainPairView
class CustomTokenObtainPairView(TokenObtainPairView):
serializer_class = CustomTokenObtainPairSerializer