Django Rest Framework-未提供身份验证凭据

我正在开发一个 API 使用 Django 休息框架。我尝试列出或创建一个“ Order”对象,但是当我尝试访问控制台时,出现了以下错误:

{"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,)

序列化程序:

class OrderSerializer(serializers.HyperlinkedModelSerializer):


class Meta:
model = Order
fields = ('field1', 'field2')

还有我的网址:

# -*- 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."}
179155 次浏览

通过在 setings.py 中添加“ DEFAULT _ AUTHENTATION _ CLASSES”解决了这个问题

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

对于其他人来说,如果您的 request.userAnonymousUser,而不是实际授权访问 URL 的正确用户,那么这个问题就会出现。您可以通过打印 request.user的值来看到这一点。如果它确实是一个匿名用户,这些步骤可能会有所帮助:

  1. 确保 INSTALLED_APPS中的 'rest_framework.authtoken'settings.py中。

  2. 确保你在 settings.py的某个地方有这个:

    REST_FRAMEWORK = {
    
    
    'DEFAULT_AUTHENTICATION_CLASSES': (
    'rest_framework.authentication.TokenAuthentication',
    # ...
    ),
    
    
    # ...
    }
    
  3. Make sure you have the correct token for the user who is logged in. If you do not have the token, learn how to get it here. Basically, you need to do a POST request to a view which gives you the token if you provide the correct username and password. Example:

    curl -X POST -d "user=Pepe&password=aaaa"  http://localhost:8000/
    
  4. Make sure the view which you are trying to access, has these:

    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,)
    # ...
    
  5. Use curl now this way:

    curl -X (your_request_method) -H  "Authorization: Token <your_token>" <your_url>
    

Example:

    curl -X GET http://127.0.0.1:8001/expenses/  -H "Authorization: Token 9463b437afdd3f34b8ec66acda4b192a815a15a8"

如果使用 mod _ wsgi 在 Apache 上运行 Django,则必须添加

WSGIPassAuthorization On

否则,授权标头将被 mod_wsgi剥离。

这有助于我在 setings.py 中不使用“ DEFAULT _ PERMISION _ CLASSES”

REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
'PAGE_SIZE': 10
}

如果您正在使用命令行(使用 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 --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"

或者类似 高级休息客户端(ARC)的东西

settings.py中添加 SessionAuthentication将完成这项工作

REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
),
}

我也面临着同样的问题,因为我错过了加法

Entication _ classes = (TokenAuthentication)

在我的 API 视图类中。

class ServiceList(generics.ListCreateAPIView):
authentication_classes = (SessionAuthentication, BasicAuthentication, TokenAuthentication)
queryset = Service.objects.all()
serializer_class = ServiceSerializer
permission_classes = (IsAdminOrReadOnly,)

除了上述内容之外,我们还需要在 setings.py 文件中显式地告诉 Django 关于 认证的内容。

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

因为它是会话登录,所以您需要提供您的凭据 我也是 127.0.0:8000/admin 管理和登录后,它将工作良好

对于我来说,我必须在 Django DRF 上用“ JWT”而不是“ Bearer”或“ Token”来预置我的 Authorization 头。然后就开始起作用了。 例如

Authorization: JWT asdflkj2ewmnsasdfmnwelfkjsdfghdfghdv.wlsfdkwefojdfgh

如果您使用的是 authentication_classes,那么您应该有 is_active作为 TrueUser模式,这可能是 False默认。

我和邮递员有点问题,把这个加到标题里..。 enter image description here

试试这个,对我管用。

在设置中

SIMPLE_JWT = {
....
...
# Use JWT
'AUTH_HEADER_TYPES': ('JWT',),
# 'AUTH_HEADER_TYPES': ('Bearer',),
....
...
}

再加上这个

REST_FRAMEWORK = {
....
...
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
)
...
..
}

还要确保 Authorization Token/API 密钥实际上是有效的。如果键也是无效的,那么 Authentication credentials were not provided.错误消息似乎就是 API 返回的内容(我在意外使用错误的 API 键时遇到了这个问题)。

如果有人从 全堆栈反应与姜戈[5]-姜戈令牌认证-争议媒体来这里,所以你需要这样的东西

帐户/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

如果您正在使用 CDN,请检查在将请求转发到服务器时,CDN 是否没有删除请求头。

在我的例子中,TokenAuthentication 丢失了

@authentication_classes([SessionAuthentication, BasicAuthentication])

我把它改成了下面,它起作用了

@authentication_classes([SessionAuthentication, BasicAuthentication, TokenAuthentication])