Как вернуть пользовательские данные с помощью маркеров доступа и обновления, чтобы идентифицировать пользователей в 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
Другие вопросы по тегам