使用 JWT 令牌对 Django Rest Framework 中的 POST 请求的未授权响应

Unauthorized response to POST request in Django Rest Framework with JWT Token

我正在使用 Django Rest Framework 构建 REST API。我目前遇到一个问题,我的一些端点 return HTTP 401 未经授权,而我的绝大多数端点 return 正确响应。对于身份验证,我使用 djangorestframework-simplejwt 的 JWT 令牌。

我已将 Django 配置为使用 djangorestframework-simplejwt 的令牌身份验证。

# rest framework config settings
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
        # 'rest_framework.permissions.AllowAny',
    ],
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ],

当我在请求中传递有效的访问令牌时,我的绝大多数端点 return 有效数据。如果我没有发送有效令牌,我会收到 HTTP 403。

另一方面,我有一些自定义 API 视图,其中 return HTTP 401 无论我是否传递有效令牌。

我已将代码包含在下面我的一个有问题的视图中。

class CheckDifferentialView(generics.GenericAPIView):
    permission_classes = [IsAuthenticated]
    authentication_classes = [TokenAuthentication]
    serializer_class = QuizDifferentialSerializer

    def post(self, request, *args, **kwargs):
        """
            A function to check a quiz question and to update a user's record of questions answered
        """
        print(request.META)
        if 'answer' not in request.data:
            return JsonResponse({'Error': 'answer not found in request'}, status=status.HTTP_400_BAD_REQUEST)

        answer = get_object_or_404(Differential, pk=request.data['answer'])
        serializer = QuizDifferentialSerializer(answer)

        if answer.is_correct:
            pass
            # record correct results
        else:
            pass
            # record failed result

        return Response(serializer.data, status=status.HTTP_200_OK)

这是我用来测试 API

的脚本
import requests
import json

POST_LOGIN_URL = 'http://localhost:8000/api/v1/token/'
POST_URL= 'http://localhost:8000/api/v1/check_differential'
REQUEST_URL = 'http://localhost:8000/api/v1/users'

with requests.Session() as session:
    post = session.post(POST_LOGIN_URL, json={"username": "j", "monkey": "aphextwin21"})
    token = json.loads(post.text)['access']
    headers = {'Authorization': 'Bearer ' + token}

    r = session.post(POST_URL, headers=headers, json={"answer": "2"})
    # r = session.get(REQUEST_URL, headers=headers)
    print(token)

print(r.text, r.status_code)

所需的行为是,如果我向此端点发送一个带有有效令牌的 POST 请求,该端点将授权我并继续其一天。如果没有提供具有有效访问令牌的授权 header,那么我希望它会拒绝请求。


更新


热心的马丁好心指出

authentication_classes = [TokenAuthentication]

正在覆盖我的设置文件中的默认设置。我不知道就 Django 而言,TokenAuthentication 和 JWTAuthentication 的处理方式不同。现在我知道了。

从我的视图中删除 authentication_classess = [TokenAuthentication] 后,视图正常工作。

视图的身份验证 class 明确设置为仅 TokenAuthentication。它不适用于 JWT 令牌。

 authentication_classes = [TokenAuthentication]

您要么删除它让默认的 classes 处理它,要么将其更改为接受 JWTAuthentication.