【问题标题】:Unauthorized response to POST request in Django Rest Framework with JWT Token使用 JWT 令牌对 Django Rest Framework 中的 POST 请求进行未经授权的响应
【发布时间】:2020-02-15 07:31:56
【问题描述】:

我正在使用 Django Rest Framework 构建一个 REST API。我目前有一个问题,我的一些端点返回 HTTP 401 Unauthorized,而我的绝大多数端点返回正确的响应。对于身份验证,我将 JWT 令牌与 djangorestframework-simplejwt 一起使用。

我已将 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',
    ],

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

另一方面,我有一些自定义 API 视图,无论我是否传递了有效令牌,它们都会返回 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 请求,该端点将授权我并继续其工作。如果没有给出具有有效访问令牌的授权标头,那么我希望它会拒绝该请求。


更新


热心的马丁请指出

authentication_classes = [TokenAuthentication]

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

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

【问题讨论】:

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


    【解决方案1】:

    视图的身份验证类仅显式设置为TokenAuthentication。它不适用于 JWT 令牌。

     authentication_classes = [TokenAuthentication]
    

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

    【讨论】:

    • 刚刚为您完成了@anowlinorbit(包括对您的问题的赞成票)。您至少需要 15 个 repo 才能进行投票。同时,您可以将答案标记为已接受,您将获得 +2,因为答案不是您的。
    猜你喜欢
    • 2018-06-05
    • 2017-10-03
    • 1970-01-01
    • 2020-09-12
    • 2019-11-26
    • 2022-06-27
    • 2023-03-18
    • 2019-05-22
    • 2017-12-27
    相关资源
    最近更新 更多