JWT Выход из системы «подробно»: «Учетные данные для аутентификации не были предоставлены».

#django #django-rest-framework #jwt #postman #django-rest-framework-simplejwt

#django #django-rest-framework #jwt #почтальон #django-rest-framework-simplejwt

Вопрос:

Я пытаюсь создать конечную точку выхода из системы для токена jwt в djangorestframework. Когда я получаю доступ к этой конечной точке через postman, я понимаю "detail": "Authentication credentials were not provided." , чего мне здесь не хватает?

  1. Должен ли я создать сериализатор, в котором есть поле для токена обновления, и добавить его в представление?
  2. Правильно ли я анализирую данные в postman?

views.py

 from rest_framework.permissions import IsAuthenticated
from rest_framework_simplejwt.tokens import RefreshToken


class LogoutView(APIView):
    permission_classes = (IsAuthenticated,)

    def post(self, request):
        try:
            refresh_token = request.data["refresh_token"]
            token = RefreshToken(refresh_token)
            token.blacklist()

            return Response(status=status.HTTP_205_RESET_CONTENT)
        except Exception as e:
            return Response(status=status.HTTP_400_BAD_REQUEST)
 

urls.py

 from accounts.views.user_api_views import (
    LogoutView,
    LogoutAllView,
)

urlpatterns = [
    path("auth/", include("djoser.urls")),
    path("auth/", include("djoser.urls.jwt")),
    path("auth/token/", ObtainCustomizedTokenView.as_view(), name="token_obtain_pair"),
    path(
        "auth/token/refresh/",
        jwt_views.TokenRefreshView.as_view(),
        name="token_refresh",
    ),
    path("logout/", LogoutView.as_view(), name="logout"),
    path("logout_all/", LogoutAllView.as_view(), name="logout_all"),
]
 

settings.py

 INSTALLED_APPS = [
    ...
    # local apps
    # 3rd party
    "storages",
    "rest_framework",
    "rest_framework_gis",
    "rest_framework.authtoken",
    "djoser",
    "django_celery_beat",
    "raven.contrib.django.raven_compat",
    "rest_framework_simplejwt.token_blacklist",
]

......
SIMPLE_JWT = {
    "ACCESS_TOKEN_LIFETIME": timedelta(weeks=521),  # 10 years
    "REFRESH_TOKEN_LIFETIME": timedelta(weeks=521),
    "ROTATE_REFRESH_TOKENS": True,
    "BLACKLIST_AFTER_ROTATION": True,
    "ALGORITHM": "HS256",
    "SIGNING_KEY": SECRET_KEY,
    "VERIFYING_KEY": None,
    "AUTH_HEADER_TYPES": ("JWT",),
    "USER_ID_FIELD": "id",
    "USER_ID_CLAIM": "user_id",
    "AUTH_TOKEN_CLASSES": ("rest_framework_simplejwt.tokens.AccessToken",),
    "TOKEN_TYPE_CLAIM": "token_type",
}

......
REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": (
        "rest_framework_simplejwt.authentication.JWTAuthentication",
    ),
    "DEFAULT_PARSER_CLASSES": [
        "rest_framework.parsers.JSONParser",
        "rest_framework.parsers.FormParser",
        "rest_framework.parsers.MultiPartParser",
    ],
    "DEFAULT_PERMISSIONS_CLASSES": ("rest_framework.permissions.IsAuthenticated"),
}
 

Изображение от Postman
введите описание изображения здесь

Ответ №1:

Я решил это, удалив параметр "AUTH_HEADER_TYPES": ("JWT",) из настроек SIMPLE_JWT. Мои настройки изменили файл настроек следующим образом:

 SIMPLE_JWT = {
    "ACCESS_TOKEN_LIFETIME": timedelta(weeks=521),  # 10 years
    "REFRESH_TOKEN_LIFETIME": timedelta(weeks=521),
    "ROTATE_REFRESH_TOKENS": True,
    "BLACKLIST_AFTER_ROTATION": True,
    "ALGORITHM": "HS256",
    "SIGNING_KEY": SECRET_KEY,
    "VERIFYING_KEY": None,
    "USER_ID_FIELD": "id",
    "USER_ID_CLAIM": "user_id",
    "AUTH_TOKEN_CLASSES": ("rest_framework_simplejwt.tokens.AccessToken",),
    "TOKEN_TYPE_CLAIM": "token_type",
}
 

В качестве альтернативы, добавление носителя в список "AUTH_HEADER_TYPES": ("JWT","Bearer") также сработало. При выборе типа авторизации в postman он дает вам возможность Bearer Token . Это означает, что представление будет искать заголовок, содержащий шаблон Authorization: Bearer <token> .