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

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

我正在使用Django Rest Framework开发API。我试图列出或创建“订单”对象,但是当我尝试访问控制台时,出现此错误:

{"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."}

I’m developing an API using Django Rest Framework. I’m trying to list or create an “Order” object, but when i’m trying to access the console gives me this error:

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

Views:

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')

And my URLs:

# -*- 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)),
)

And then I’m using this command in the console:

curl -X GET http://127.0.0.1:8000/api/orders/ -H 'Authorization: Token 12383dcb52d627eabd39e7e88501e96a2sadc55'

And the error say:

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

回答 0

如果您使用mod_wsgi在Apache上运行Django,则必须添加

WSGIPassAuthorization On

在您的httpd.conf中。否则,授权标头将被mod_wsgi剥离。

If you are runnig Django on Apache using mod_wsgi you have to add

WSGIPassAuthorization On

in your httpd.conf. Otherwise authorization header will be stripped out by mod_wsgi.


回答 1

通过在我的settings.py中添加“ DEFAULT_AUTHENTICATION_CLASSES”来解决

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

Solved by adding “DEFAULT_AUTHENTICATION_CLASSES” to my settings.py

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

回答 2

这可以帮助我在settings.py中没有“ DEFAULT_PERMISSION_CLASSES”的情况

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

This help me out without “DEFAULT_PERMISSION_CLASSES” in my settings.py

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

回答 3

仅对于其他人,由于同样的错误而以同样的错误登陆,如果您request.user是您AnonymousUser的用户,而不是实际有权访问URL的正确用户,则可能会出现此问题。您可以通过打印的值看到这一点request.user。如果确实是匿名用户,这些步骤可能会有所帮助:

  1. 请确保您有 'rest_framework.authtoken'INSTALLED_APPS你的settings.py

  2. 确保您在settings.py以下位置有此商品:

    REST_FRAMEWORK = {
    
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework.authentication.TokenAuthentication',
            # ...
        ),
    
        # ...
    }
  3. 确保您具有登录用户的正确令牌。如果没有令牌,请在此处了解如何获取令牌。基本上,POST如果您提供正确的用户名和密码,则需要对视图进行请求,该视图将为您提供令牌。例:

    curl -X POST -d "user=Pepe&password=aaaa"  http://localhost:8000/
  4. 确保您尝试访问的视图具有以下内容:

    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. 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"

Just for other people landing up here with same error, this issue can arise if your request.user is AnonymousUser and not the right user who is actually authorized to access the URL. You can see that by printing value of request.user . If it is indeed an anonymous user, these steps might help:

  1. Make sure you have 'rest_framework.authtoken' in INSTALLED_APPS in your settings.py.

  2. Make sure you have this somewhere in 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"

回答 4

如果您在命令行中玩耍(使用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)的东西

If you are playing around in the command line (using curl, or HTTPie etc) you can use BasicAuthentication to test/user your 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',
        )
    }

You can then use curl

curl --user user:password -X POST http://example.com/path/ --data "some_field=some data"

or httpie (its easier on the eyes):

http -a user:password POST http://example.com/path/ some_field="some data"

or something else like Advanced Rest Client (ARC)


回答 5

我也遇到了同样的事情,因为我错过了添加

authentication_classes =(令牌认证)

在我的API视图类中。

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

除了上述内容外,我们还需要在settings.py文件中明确告知Django 身份验证

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

I too faced the same since I missed adding

authentication_classes = (TokenAuthentication)

in my API view class.

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

In addition to the above, we need to explicitly tell Django about the Authentication in settings.py file.

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

回答 6

在settings.py中添加SessionAuthentication就可以了

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

Adding SessionAuthentication in settings.py will do the job

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


回答 7

由于它是会话登录,因此您需要提供凭据,因此可以先进行 127.0.0:8000/admin 管理员登录,然后再正常运行

Since it is session Login so you need to provide you credentials so do 127.0.0:8000/admin admin and login later it will work fine


回答 8

对我来说,我必须在Django DRF上的Authorization标头前面加上“ JWT”,而不是“ Bearer”或“ Token”。然后它开始工作。例如-

Authorization: JWT asdflkj2ewmnsasdfmnwelfkjsdfghdfghdv.wlsfdkwefojdfgh

For me, I had to prepend my Authorization header with “JWT” instead of “Bearer” or “Token” on Django DRF. Then it started working. eg –

Authorization: JWT asdflkj2ewmnsasdfmnwelfkjsdfghdfghdv.wlsfdkwefojdfgh


回答 9

如果你正在使用authentication_classes,那么你应该有is_active作为TrueUser模型,这可能是False默认。

If you are using authentication_classes then you should have is_active as True in User model, which might be False by default.