JWT 注销“详细信息”:“未提供身份验证凭据。”

时间:2021-03-21 16:06:17

标签: django django-rest-framework jwt postman django-rest-framework-simplejwt

我正在尝试为 djangorestframework 中的 jwt 令牌创建一个注销端点。当我通过邮递员访问此端点时,我得到 "detail": "Authentication credentials were not provided." 我在这里错过了什么?

  1. 我是否应该创建一个包含刷新令牌字段的序列化程序并将其添加到视图中?
  2. 我在邮递员中正确解析了数据吗?

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 的图片 enter image description here

1 个答案:

答案 0 :(得分:0)

我通过从 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") 的列表也有效。在 postman 中选择授权类型时,它提供了 Bearer Token 选项。这意味着,视图将查找包含模式 Authorization: Bearer <token> 的标题。