JWT 注销 "detail":"Authentication credentials were not provided."

JWT Logout "detail": "Authentication credentials were not provided."

我正在尝试在 djangorestframework 中为 jwt 令牌创建注销端点。当我通过邮递员访问此端点时,我得到 "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

我通过从 SIMPLE_JWT 设置中删除设置 "AUTH_HEADER_TYPES": ("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",
}

或者,将 Bearer 添加到 "AUTH_HEADER_TYPES": ("JWT","Bearer") 的列表中也有效。在邮递员中选择授权类型时,它会给你 Bearer Token 的选项。这意味着,视图将查找包含模式 Authorization: Bearer <token>.

的 header