Django возвращает «Учетные данные для аутентификации не были предоставлены» при попытке аутентификации с помощью токена

(я пробовал решения в похожих вопросах, но они мне не подошли).

Я создаю простое веб-приложение на основе Django REST, в котором пользователь будет регистрироваться, создавать некоторые события, позже входить в систему и просматривать события.

Вот вид события:

class EventGetCreate(APIView):
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)

    def get(self, request):
        created_user = request.user
        events = Event.objects.filter(creator=created_user)
        serializer = EventSummary(events, many=True)
        return Response(serializer.data)

Его файл urls.py выглядит следующим образом:

from django.urls import path, include

from . import views

app_name = 'event'

urlpatterns = [
    ...
    path('eventviewall/', views.EventGetCreate.as_view()),
]

В файле core/urls.py для получения токена используется следующее:

from .views import UserViewSet
from rest_framework.authtoken.views import ObtainAuthToken, obtain_auth_token

app_name = 'core'

router = routers.DefaultRouter()
router.register('users', UserViewSet)

urlpatterns = [
    path('auth/', obtain_auth_token),
    path('register/', include(router.urls)),
]

Используя postman, я могу успешно войти в систему и получить токен: Отправьте запрос на http://127.0.0.1:8000/api/auth/ и получите следующее (пример токена):

{
    "token": "xxyyzz"
}

Теперь я хочу отправить этот токен в запросе get и просмотреть события, созданные пользователем. Я отправляю запрос на http://127.0.0.1:8000/event/eventviewall/, с указанным выше токеном, установленным на вкладке Authorization -> Bearer token.

Однако я получаю следующий ответ:

{
    "detail": "Authentication credentials were not provided."
}

Теперь, если я установлю permission_classes = () в представлении выше (как было предложено в некоторых ответах на похожие вопросы), я получу следующую ошибку:

TypeError at /event/eventviewall/
Field 'id' expected a number but got <django.contrib.auth.models.AnonymousUser object at 0x0000018BEF4573A0>.

Я получаю, что эта ошибка возникает из-за того, что Django устанавливает для request.user значение AnonymousUser, так как не может аутентифицировать пользователя.

Как это исправить?

Проблема в том, что это не Bearer Token. Вы должны предоставить свой собственный заголовок Authorization со значением Token: <token>. Такие приложения, как Postman, не имеют встроенного заголовка авторизации такого типа, поэтому вам нужно добавить его вручную.

Проблема заключается в разборе заголовка auth (вы используете неожиданное значение заголовка Bearer). Исправление заключается в том, чтобы либо изменить значение заголовка, либо изменить ожидаемое значение (оба варианта возможны).

Подробности непосредственно с сайта https://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication:

Для аутентификации клиентов ключ токена должен быть включен в HTTP-заголовок авторизации. Ключ должен иметь префикс в виде строки литерал «Token», с пробелами, разделяющими эти две строки. Для например:

Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b

Если вы хотите использовать другое ключевое слово в заголовке, например Bearer, просто создайте подкласс TokenAuthentication и установите переменную класса keyword. переменную.

Вернуться на верх