Django Rest Framework - учетные данные для аутентификации не предоставлены
Я разрабатываю API с использованием Django Rest Framework. Я пытаюсь перечислить или создать объект "Порядок", но когда я пытаюсь получить доступ к консоли, выдает мне эту ошибку:
{"detail": "Authentication credentials were not provided."}
Просмотры:
from django.shortcuts import render
from rest_framework import viewsets
from django.contrib.auth.models import User
from rest_framework.renderers import JSONRenderer, YAMLRenderer
from rest_framework.response import Response
from rest_framework.views import APIView
from order.models import *
from API.serializers import *
from rest_framework.permissions import IsAuthenticated
class OrderViewSet(viewsets.ModelViewSet):
model = Order
serializer_class = OrderSerializer
permission_classes = (IsAuthenticated,)
Serializer:
class OrderSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Order
fields = ('field1', 'field2')
И мои URL:
# -*- coding: utf-8 -*-
from django.conf.urls import patterns, include, url
from django.conf import settings
from django.contrib import admin
from django.utils.functional import curry
from django.views.defaults import *
from rest_framework import routers
from API.views import *
admin.autodiscover()
handler500 = "web.views.server_error"
handler404 = "web.views.page_not_found_error"
router = routers.DefaultRouter()
router.register(r'orders', OrdersViewSet)
urlpatterns = patterns('',
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^api-token-auth/', 'rest_framework.authtoken.views.obtain_auth_token'),
url(r'^api/', include(router.urls)),
)
И тогда я использую эту команду в консоли:
curl -X GET http://127.0.0.1:8000/api/orders/ -H 'Authorization: Token 12383dcb52d627eabd39e7e88501e96a2sadc55'
И об ошибке говорят:
{"detail": "Authentication credentials were not provided."}
20 ответов
Решено добавлением "DEFAULT_AUTHENTICATION_CLASSES" в мои settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAdminUser'
),
}
Если вы запускаете Django на Apache, используя mod_wsgi, вы должны добавить
WSGIPassAuthorization On
в вашем httpd.conf. В противном случае заголовок авторизации будет удален mod_wsgi.
Это поможет мне без "DEFAULT_PERMISSION_CLASSES" в моих settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
'PAGE_SIZE': 10
}
Просто для других людей, приземляющихся здесь с той же ошибкой, эта проблема может возникнуть, если ваш request.user
является AnonymousUser
и не тот пользователь, который действительно авторизован для доступа к URL. Вы можете увидеть это, напечатав значение request.user
, Если это действительно анонимный пользователь, эти шаги могут помочь:
Убедитесь, что у вас есть
'rest_framework.authtoken'
вINSTALLED_APPS
в вашемsettings.py
,Убедитесь, что у вас есть это где-то в
settings.py
:REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.TokenAuthentication', # ... ), # ... }
Убедитесь, что у вас есть правильный токен для пользователя, который вошел в систему. Если у вас нет токена, узнайте, как его получить, здесь. В основном вам нужно сделать
POST
запрос на просмотр, который дает вам токен, если вы предоставите правильное имя пользователя и пароль. Пример:curl -X POST -d "user=Pepe&password=aaaa" http://localhost:8000/
Убедитесь, что представление, к которому вы пытаетесь получить доступ, имеет следующее:
class some_fancy_example_view(ModelViewSet): """ not compulsary it has to be 'ModelViewSet' this can be anything like APIview etc, depending on your requirements. """ permission_classes = (IsAuthenticated,) authentication_classes = (TokenAuthentication,) # ...
использование
curl
теперь так:curl -X (your_request_method) -H "Authorization: Token <your_token>" <your_url>
Пример:
curl -X GET http://127.0.0.1:8001/expenses/ -H "Authorization: Token 9463b437afdd3f34b8ec66acda4b192a815a15a8"
Если вы играете в командной строке (используя curl, HTTPie и т. Д.), Вы можете использовать BasicAuthentication для тестирования / использования вашего API
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication', # enables simple command line authentication
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
)
}
Затем вы можете использовать curl
curl --user user:password -X POST http://example.com/path/ --data "some_field=some data"
или httpie (это легче для глаз):
http -a user:password POST http://example.com/path/ some_field="some data"
или что-то еще, как Advanced Rest Client (ARC)
Мне пришлось добавить к заголовку авторизации "JWT" вместо "Bearer" или "Token" в Django DRF. Потом заработало. например -
Authorization: JWT asdflkj2ewmnsasdfmnwelfkjsdfghdfghdv.wlsfdkwefojdfgh
Я тоже сталкивался с тем же, так как я пропустил добавление
authentication_classes = (TokenAuthentication)
в моем классе просмотра API.
class ServiceList(generics.ListCreateAPIView):
authentication_classes = (SessionAuthentication, BasicAuthentication, TokenAuthentication)
queryset = Service.objects.all()
serializer_class = ServiceSerializer
permission_classes = (IsAdminOrReadOnly,)
В дополнение к вышесказанному, нам нужно явно сообщить Django об аутентификации в файле settings.py.
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
)
}
Наверное, это могло сработать
В settings.py
SIMPLE_JWT = {
....
...
# Use JWT
'AUTH_HEADER_TYPES': ('JWT',),
# 'AUTH_HEADER_TYPES': ('Bearer',),
....
...
}
Добавьте это тоже
REST_FRAMEWORK = {
....
...
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
)
...
..
}
Добавление SessionAuthentication в settings.py сделает работу REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
),
}
if anyone come here from Full Stack React &amp; Django [5] - Django Token Authentication - Traversy Media So you need to something like this
accounts/api.py
from rest_framework import generics, permissions
from rest_framework.response import Response
from knox.models import AuthToken
from .serializers import LoginSerializer, RegisterSerializer, UserSerializer
from knox.auth import TokenAuthentication
# Register Api
class RegisterAPI(generics.GenericAPIView):
serializer_class = RegisterSerializer
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.save()
return Response({
"user": UserSerializer(user, context=self.get_serializer_context()).data,
"token": AuthToken.objects.create(user)[1]
})
# Login Api
class LoginAPI(generics.GenericAPIView):
serializer_class = LoginSerializer
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.validated_data
return Response({
"user": UserSerializer(user, context=self.get_serializer_context()).data,
"token": AuthToken.objects.create(user)[1]
})
# Get User Api
class UserAPI(generics.RetrieveAPIView):
authentication_classes = (TokenAuthentication,)
permission_classes = [
permissions.IsAuthenticated,
]
serializer_class = UserSerializer
def get_object(self):
return self.request.user
В моем случае TokenAuthentication отсутствовал
@authentication_classes([SessionAuthentication, BasicAuthentication])
Я изменил его на ниже, и это сработало
@authentication_classes([SessionAuthentication, BasicAuthentication, TokenAuthentication])
Также убедитесь, что токен авторизации / ключ API действительно действителен. В
Поскольку это сеанс входа, вам необходимо предоставить учетные данные, поэтому
127.0.0:8000/admin
admin и войдите позже, он будет работать нормально
Если вы используете authentication_classes
тогда у тебя должно быть is_active
как True
в User
модель, которая может быть False
по умолчанию.
Я добавил это в settings.py:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
}
и я создал суперпользователя и создал токен, используя:
python manage.py createsuperuser
и создал токен, используяhttp://127.0.0.1:8000/admin/authtoken/tokenproxy/
и ничего больше, и это просто работало.
Если вы используете CDN, убедитесь, что CDN не удаляет заголовок запроса при пересылке запроса на ваш сервер.
У меня была такая же проблема с почтальоном и бэкэндом Django. Я использовалBearer token
но это начало давать сбой, мне пришлось вручную добавитьAuthorization
Заголовок включенHeaders
предваряя егоToken
т.е.Token token
У меня была странная проблема с этой ошибкой.
Я правильно получал токен, правильно передал токен авторизации в Postman и все еще получал эту ошибку.
{"detail": "Authentication credentials were not provided."}
Я искал это в Интернете и проверил много вопросов SO. Но ничего не помогло.
Затем я закрыл приложение Postman и перезапустил его, и все заработало. Я понятия не имел, почему Почтальон так себя вел.
К счастью, проблема решена :)
Я бы также добавил это для тех, кто хочет реализовать аутентификацию только по токену. Убедитесь, что ваш набор представлений имеет атрибут «authentication_classes».
Например:
from rest_framework.authentication import TokenAuthentication
class TaskViewSet(viewsets.ModelViewSet):
"""
Tasks for the current user. This endpoint allows tasks to be viewed or edited.
"""
queryset = Task.objects.all().order_by('-created_at')
serializer_class = TaskSerializer
authentication_classes = [TokenAuthentication]
permission_classes = [permissions.IsAuthenticated]
Это позволит обойти требование о том, чтобы имя пользователя и пароль пользователя запрашивались в запросе сеанса.