Проверка подлинности токена в django (rest_framework) не работает - PullRequest
0 голосов
/ 30 октября 2019

заголовок говорит сам за себя. Я пытаюсь аутентифицироваться с помощью токена. Я получаю информацию из базы данных Django в мое приложение. Я успешно извлек свой токен из rest_framework и добавил его в заголовки запроса rest. Я напечатал эти заголовки в django, что приводит к

{
  'Content-Length': '0', 
  'Content-Type': 'text/plain', 
  'User-Agent': 'Dart/2.5 (dart:io)', 
  'Accept-Encoding': 'gzip', 
  'Authorization': 'Token 10cf58e1402b8e48c1a455aaff7f7bcf53e24231', 
  'Host': '192.168.0.110:8000'
}

В результате получается веб-страница с формой входа в систему, а не остальные данные, которые я запрашивал. Чего мне не хватает?

settings.py

...
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated', 
    )
}
...

views.py

...
@login_required
@csrf_exempt
def ui_list(request):
    print(request.headers)
    """
    List all code user_informations, or create a new user_information.
    """
    if request.method == "GET":
        users = UserInformation.objects.all()
        serializer = UserInformationSerializer(users, many=True)
        return JsonResponse(serializer.data, safe=False)

    elif request.method == "POST":
        data = JSONParser().parse(request)
        serializer = UserInformationSerializer(data=data)
        if serializer.is_valid():
            serializer.save()
            return JsonResponse(serializer.data, status=201)
        return JsonResponse(serializer.errors, status=400)
...

Ответы [ 2 ]

1 голос
/ 30 октября 2019

Этот login_required не является rest_framework способом аутентификации. Вам нужно использовать класс разрешений для аутентификации через ваш API, если это то, что вы пытаетесь сделать.
Как я это реализовал, я создал представление для входа в систему

class LoginView(APIView):
    """Class based view loggin in user and returning Auth Token."""

    authentication_classes = [TokenAuthentication]
    permission_classes = [AllowAny]

    def post(self, request):
        """Check if user exists, return token if it does."""
        data = JSONParser().parse(request)
        serializer_obj = LoginObjectSerializer(data=data)
        if serializer_obj.is_valid():
            user = authenticate(username=serializer_obj.data['username'], password=serializer_obj.data['password'])
            if not user:
                return Response({'error': 'Invalid Credentials'}, status=404)
            token, _ = Token.objects.get_or_create(user=user)
            return Response({'token': token.key}, status=200)

        return JsonResponse(serializer_obj.errors, status=400)

И как я аутентифицировал свои APIбыло с использованием rest-framework предоставленных классов разрешений вместо @login_required. Мой settings.py имеет

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated', )
}

, и класс разрешений, который я использовал для защиты своих представлений, был таким:

from rest_framework.permissions import AllowAny, IsAuthenticated

authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated]

Но я использовал это в представлениях на основе классов. Для метода, основанного на методе, вы можете сделать это, как указано здесь

@permission_classes([IsAuthenticated])

Суть в том, что вы пытаетесь использовать аутентификацию на основе токена, но на самом деле вы ее не используете. Создайте свой собственный API для входа в систему и используйте его, как указано в этом ответе или ответе @ sebastienbarbier.

0 голосов
/ 30 октября 2019

Ваша проблема возникла из-за использования декоратора @login_required, который должен защищать представление django .

Представления Django и django_rest_framework не используют одну и ту же систему аутентификации и поэтому должны быть реализованы по-разному.

Ручная аутентификация

Вы можете удалить @login_required и внедрите view.py следующим образом:

from rest_framework.authentication import TokenAuthentication
...
@csrf_exempt
def ui_list(request):
    print(request.headers)
    """
    List all code user_informations, or create a new user_information.
    """
    if request.method == "GET":

        user_auth_tuple = TokenAuthentication().authenticate(request)
        if user_auth_tuple is None:
            return HttpResponse(status=401)
        else:
            (user, token) = user_auth_tuple # here come your user object

            users = UserInformation.objects.all()
            serializer = UserInformationSerializer(users, many=True)
            return JsonResponse(serializer.data, safe=False)

    if request.method == "POST":
         ...
...

Но выполнение этого процесса вручную отнимает много времени, не следует делать таким образом , так как DRSF предоставляет множество опций, чтобы сделать это автоматическим.

Представление на основе классов

Что на самом деле нужно сделать, это сопоставить django-фреймворк для отдыха класса APIView с вашей моделью и сгенерировать подходящую точку входа, используя систему разрешений.

REST framework предоставляет класс APIView , который подклассы класса View Джанго.

Классы APIView отличаются отОбычные классы просмотра выполняются следующими способами:

  • Запросы, передаваемые методам-обработчикам, будут экземплярами Request платформы REST экземпляров, а не HttpRequest ins Django. tances.
  • Методы-обработчики могут возвращать Response фреймворка REST вместо HttpResponse Джанго. Представление будет управлять согласованием содержимого и устанавливать правильный рендерер для ответа .
  • Любые исключения APIException будут перехвачены и переданы в соответствующие ответы.
  • Входящие запросы будет проверено подлинность, и перед отправкой запроса методу обработчика будут выполнены соответствующие разрешения и / или проверки газа.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...