Django Rest Framework - Authentifizierungsdaten wurden nicht bereitgestellt

94

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, wird folgende Fehlermeldung angezeigt:

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

Ansichten:

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

Und 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."}
Marcos Aguayo
quelle
5
Versuchen Sie dies:curl -H "Authorization: Token 12383dcb52d627eabd39e7e88501e96a2sadc55" http://127.0.0.1:8000/api/orders/
Cor
1
Gleicher Fehler. Authentifizierungsdaten wurden nicht angegeben
Marcos Aguayo
In meinem Fall geschah dies, weil ein Teamkollege den Benutzer in den inaktiven Modus schaltete.
Brock
Versuchen Sie zuerst, die Authentifizierung zu lesen .
endlos
@endless Die Frage war vor 3 Jahren. Es ist bereits gelöst
Marcos Aguayo

Antworten:

157

Wenn Sie Django auf Apache mit mod_wsgi ausführen, müssen Sie hinzufügen

WSGIPassAuthorization On

in Ihrer httpd.conf. Andernfalls wird der Autorisierungsheader von mod_wsgi entfernt.

Robert Kovac
quelle
1
Wenn Sie sich fragen, wo Sie dies schreiben sollen, folgen Sie dem Link. stackoverflow.com/questions/49340534/…
user2858738
1
für Ubuntu scheint es keine zu geben httpd.conf. so muss man hinzufügen , WSGIPassAuthorization Onin/etc/apache2/apache2.conf
suhailvs
Ich war verwirrt von einem Problem, bei dem meine Anfragen von Postman von meinem lokalen Host aus arbeiteten, aber nicht, als sie an den Live-Server gesendet wurden. Ihr Kommentar hat mein Problem gelöst.
RommelTJ
Mein Problem wurde behoben. Ich konnte Daten über die API auf meinem lokalen Host abrufen, aber bei der Bereitstellung auf dem Server über https: // gab es denselben Fehler.
Mir Suhail
Gilt das nur für die Produktion oder auch für die lokale Entwicklung?
MadPhysicist
88

Gelöst durch Hinzufügen von "DEFAULT_AUTHENTICATION_CLASSES" zu meiner settings.py

REST_FRAMEWORK = {
   'DEFAULT_AUTHENTICATION_CLASSES': (
       'rest_framework.authentication.TokenAuthentication',
   ),
   'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAdminUser'
   ),
}
Marcos Aguayo
quelle
Dachte , ich tat dies, aber ich hatte hinzugefügt , 'rest_framework.authentication.TokenAuthentication'um DEFAULT_PERMISSION_CLASSESstattDEFAULT_AUTHENTICATION_CLASSES
netigger
4
Danke für diese Lösung! Ich verstehe jedoch nicht, warum ich nicht die "Authentifizierungsdaten wurden nicht angegeben" erhalten habe. Fehler bei der Herstellung die Anfrage mit Postman, während ich habe den Fehler , wenn mein Eckige Client - Anfragen gemacht. Beide mit dem gleichen Token im Authorization-Header ...
Sander Vanden Hautte
SessionAuthenticationist standardmäßig aktiviert und funktioniert mit den Standard-Sitzungscookies. Daher ist es wahrscheinlich, dass Ihre Angular-Anwendung (oder eine andere JS-Framework-Anwendung) aufgrund der Standard-Sitzungsauthentifizierung funktioniert hat.
Kevin Brown
26

Dies hilft mir ohne "DEFAULT_PERMISSION_CLASSES" in meiner settings.py

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ),
    'PAGE_SIZE': 10
}
uestcfei
quelle
3
Das SessionAuthenticationwar es, was es für mich
behoben
Es wurde auch für mich behoben. Ich frage mich, warum das Django-Tutorial dies nicht erwähnt. Siehe django-rest-framework.org/tutorial/quickstart .
Nick T
15

Nur für andere Personen, die mit demselben Fehler hier landen, kann dieses Problem auftreten, wenn Sie der richtige Benutzer request.usersind AnonymousUserund nicht der richtige Benutzer, der tatsächlich zum Zugriff auf die URL berechtigt ist. Sie können dies sehen, indem Sie den Wert von drucken request.user. Wenn es sich tatsächlich um einen anonymen Benutzer handelt, können folgende Schritte hilfreich sein:

  1. Vergewissern Sie sich , 'rest_framework.authtoken'in INSTALLED_APPSIhrer settings.py.

  2. Stellen Sie sicher, dass Sie dies irgendwo in settings.py:

    REST_FRAMEWORK = {
    
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework.authentication.TokenAuthentication',
            # ...
        ),
    
        # ...
    }
  3. Stellen Sie sicher, dass Sie das richtige Token für den angemeldeten Benutzer haben. Wenn Sie das Token nicht haben, erfahren Sie hier , wie Sie es erhalten . Grundsätzlich müssen Sie eine POSTAnforderung 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/
  4. Stellen Sie sicher, dass die Ansicht, auf die Sie zugreifen möchten, folgende Eigenschaften aufweist:

    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. Verwenden Sie curljetzt 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"
Sherelock
quelle
Wie kann man drucken request.user? Es scheint, dass die POST-Methode einer klassenbasierten Ansicht niemals verarbeitet wird. Wo sonst kann ich versuchen, den Benutzer zu drucken?
MadPhysicist
Der Benutzer muss authentifiziert sein, damit er im Anforderungsobjekt festgelegt werden kann. Andernfalls wird nur ein anonymer Benutzer gedruckt. Wie authentifizieren Sie Ihren Benutzer?
Sherelock
11

Wenn Sie in der Befehlszeile herumspielen (mithilfe von Curl, HTTPie usw.), können Sie mit BasicAuthentication Ihre API testen / 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 (es ist augenschonender ):

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

oder etwas anderes wie Advanced Rest Client (ARC)

lukeaus
quelle
8

Auch ich sah mich dem gegenüber, da ich das Hinzufügen verpasst hatte

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 explizit über die Authentifizierung in der Datei settings.py informieren.

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

Das Hinzufügen von SessionAuthentication in settings.py erledigt den Job

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

Pritam Roy
quelle
1

Da es sich um eine Sitzungsanmeldung handelt, müssen Sie Ihre Anmeldeinformationen 127.0.0:8000/admin angeben. Führen Sie also den Administrator aus und melden Sie sich später an. Dies funktioniert einwandfrei

Aishwarya kabadi
quelle
1
Entschuldigung, aber diese Frage wird bereits ausführlicher beantwortet als Ihre ...
Muhammad Dyas Yaskur
Dies ist für die Menschen, die eine schnelle Lösung brauchen
Aishwarya kabadi
0

Für mich musste ich meinem Authorization-Header "DWT" anstelle von "Bearer" oder "Token" in Django DRF voranstellen. Dann fing es an zu arbeiten. z.B -

Authorization: JWT asdflkj2ewmnsasdfmnwelfkjsdfghdfghdv.wlsfdkwefojdfgh

kiko carisse
quelle
0

Wenn Sie verwenden authentication_classes, sollten Sie is_activewie Trueim UserModell haben, was möglicherweise Falsestandardmäßig ist.

Piyush Jaiswal
quelle