Несанкционированный ответ на запрос POST в Django Rest Framework с токеном JWT

Я создаю REST API с помощью Django Rest Framework. В настоящее время у меня проблема, когда некоторые из моих конечных точек возвращают 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] из моих представлений представления работают так, как должны.




Ответы (1)


Класс аутентификации представления явно установлен только на TokenAuthentication. Он не будет работать с токеном JWT.

 authentication_classes = [TokenAuthentication]

Вы либо удалите это, чтобы позволить классам по умолчанию обрабатывать его, либо измените его, чтобы принять JWTAuthentication.

person Enthusiast Martin    schedule 18.10.2019
comment
Только что сделал это за вас @anowlinorbit (включая голос за ваш вопрос). Вам нужно как минимум 15 репо, чтобы иметь возможность проголосовать. А пока вы можете отметить ответ как принятый, вы получите +2, потому что ответ не ваш. - person Tiago Martins Peres 李大仁; 18.10.2019