Ich entwickle eine API mit Django Rest Framework. Ich versuche, ein "Order" -Objekt aufzulisten oder zu erstellen, aber wenn ich versuche, auf die Konsole zuzugreifen, erhalte ich diesen Fehler:
{"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')
nd meine 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)),
)
Und dann benutze ich diesen Befehl in der Konsole:
curl -X GET http://127.0.0.1:8000/api/orders/ -H 'Authorization: Token 12383dcb52d627eabd39e7e88501e96a2sadc55'
Und der Fehler sagt:
{"detail": "Authentication credentials were not provided."}
Gelöst durch Hinzufügen von "DEFAULT_AUTHENTICATION_CLASSES" zu meinen settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAdminUser'
),
}
Wenn Sie Django auf Apache mit mod_wsgi ausführen, müssen Sie hinzufügen
WSGIPassAuthorization On
in deiner httpd.conf. Andernfalls wird der Autorisierungsheader von mod_wsgi entfernt.
Dies hilft mir ohne "DEFAULT_PERMISSION_CLASSES" in meinen settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
'PAGE_SIZE': 10
}
Nur für andere Leute, die hier mit demselben Fehler landen, kann dieses Problem auftreten, wenn Ihr request.user
AnonymousUser
ist und nicht der richtige Benutzer, der tatsächlich zum Zugriff auf die URL berechtigt ist. Sie können dies sehen, indem Sie den Wert request.user
Drucken. Wenn es sich in der Tat um einen anonymen Benutzer handelt, können die folgenden Schritte hilfreich sein:
Stellen Sie sicher, dass Sie 'rest_framework.authtoken'
In INSTALLED_APPS
In Ihrem settings.py
Haben.
Stellen Sie sicher, dass Sie dies irgendwo in settings.py
Haben:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
# ...
),
# ...
}
Stellen Sie sicher, dass Sie das richtige Token für den angemeldeten Benutzer haben. Wenn Sie nicht über das Token verfügen, erfahren Sie, wie Sie es erhalten hier . Grundsätzlich müssen Sie eine POST
-Anforderung an eine Ansicht senden, die Ihnen das Token gibt, wenn Sie den richtigen Benutzernamen und das richtige Kennwort angeben. Beispiel:
curl -X POST -d "user=Pepe&password=aaaa" http://localhost:8000/
Stellen Sie sicher, dass die Ansicht, auf die Sie zugreifen möchten, folgende Informationen enthält:
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,)
# ...
Benutze curl
jetzt so:
curl -X (your_request_method) -H "Authorization: Token <your_token>" <your_url>
Beispiel:
curl -X GET http://127.0.0.1:8001/expenses/ -H "Authorization: Token 9463b437afdd3f34b8ec66acda4b192a815a15a8"
Wenn Sie in der Befehlszeile herumspielen (mit Curl oder HTTPie usw.), können Sie BasicAuthentication verwenden, um Ihre API zu testen/zu verwenden
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',
)
}
Sie können dann curl verwenden
curl --user user:password -X POST http://example.com/path/ --data "some_field=some data"
oder httpie (das schont die Augen):
http -a user:password POST http://example.com/path/ some_field="some data"
oder etwas anderes wie Advanced Rest Client (ARC)
Das habe auch ich mitgemacht, da ich das Hinzufügen verpasst habe
authentication_classes = (TokenAuthentication)
in meiner API-Ansichtsklasse.
class ServiceList(generics.ListCreateAPIView):
authentication_classes = (SessionAuthentication, BasicAuthentication, TokenAuthentication)
queryset = Service.objects.all()
serializer_class = ServiceSerializer
permission_classes = (IsAdminOrReadOnly,)
Darüber hinaus müssen wir Django) in der settings.py-Datei explizit über Authentication informieren.
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
)
}
Das Hinzufügen von SessionAuthentication in settings.py erledigt den JobREST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.SessionAuthentication', ), }