Django Rest Framework - nie podano danych uwierzytelniających


106

Rozwijam API przy użyciu Django Rest Framework. Próbuję wyświetlić lub utworzyć obiekt „Zamówienie”, ale kiedy próbuję uzyskać dostęp do konsoli, pojawia się następujący błąd:

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

Wyświetlenia:

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

Serializator:

class OrderSerializer(serializers.HyperlinkedModelSerializer):

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

I moje adresy 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)),
)

A potem używam tego polecenia w konsoli:

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

A błąd mówi:

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

5
Spróbuj tego:curl -H "Authorization: Token 12383dcb52d627eabd39e7e88501e96a2sadc55" http://127.0.0.1:8000/api/orders/
— cor

1
Ten sam błąd. Nie podano danych uwierzytelniających
— Marcos Aguayo

W moim przypadku stało się to z powodu przełączenia użytkownika przez członka drużyny w tryb nieaktywny.
— Brock

Spróbuj najpierw przeczytać Uwierzytelnianie .
— niekończący się

@endless Pytanie było 3 lata temu. To już rozwiązane
— Marcos Aguayo

Odpowiedzi:


168

Jeśli używasz Django na Apache używając mod_wsgi, musisz dodać

WSGIPassAuthorization On

w twoim httpd.conf. W przeciwnym razie nagłówek autoryzacji zostanie usunięty przez mod_wsgi.


1
Jeśli zastanawiasz się, gdzie to napisać, kliknij link. stackoverflow.com/questions/49340534/…
— user2858738

2
dla ubuntu wydaje się, że nie httpd.conf. więc trzeba dodać WSGIPassAuthorization Onw/etc/apache2/apache2.conf
— suhailvs

Byłem zdezorientowany problemem polegającym na tym, że moje żądania z Postmana działały z mojego lokalnego hosta, ale nie były wysyłane na serwer aktywny. Twój komentarz rozwiązał mój problem.
— RommelTJ

Rozwiązany Mój problem, byłem w stanie uzyskać dane przez interfejs API na moim hoście lokalnym, ale po wdrożeniu na serwerze przez https: // dawał mi ten sam błąd.
— Mir Suhail

Czy dotyczy to tylko produkcji, czy też rozwoju lokalnego?
— MadPhysicist

100

Rozwiązane przez dodanie „DEFAULT_AUTHENTICATION_CLASSES” do mojego settings.py

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

Myśl Zrobiłem to, ale ja dodaje 'rest_framework.authentication.TokenAuthentication'się DEFAULT_PERMISSION_CLASSESzamiastDEFAULT_AUTHENTICATION_CLASSES
— netigger

4
Dzięki za to rozwiązanie! Nie rozumiem jednak, dlaczego nie otrzymałem komunikatu „Nie podano danych uwierzytelniających”. Błąd podczas wykonywania żądania z Postman, natomiast ja nie pojawia się błąd, gdy mój klient kątowa wykonana żądań. Oba z tym samym tokenem w nagłówku Authorization ...
— Sander Vanden Hautte

SessionAuthenticationjest domyślnie włączona i działa ze standardowymi plikami cookie sesji, więc prawdopodobnie Twoja aplikacja Angular (lub inna platforma JS) działała z powodu domyślnego uwierzytelniania sesji.
— Kevin Brown

29

Pomoże mi to bez „DEFAULT_PERMISSION_CLASSES” w moim settings.py

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

3
To SessionAuthenticationwłaśnie rozwiązało problem
— Caleb_Allen,

Naprawiłem to też dla mnie. Ciekawe, dlaczego samouczek Django o tym nie wspomina o tym. Zobacz django-rest-framework.org/tutorial/quickstart .
— Nick T

15

Tylko dla innych ludzi lądowania tutaj z tego samego błędu, to problem może pojawić się jeśli request.userjest AnonymousUser, a nie właściwą użytkownika, który jest faktycznie uprawniony do dostępu do adresu URL. Możesz to zobaczyć, drukując wartość request.user. Jeśli rzeczywiście jest to użytkownik anonimowy, poniższe kroki mogą pomóc:

  1. Upewnij się, że 'rest_framework.authtoken'w INSTALLED_APPSna swój settings.py.

  2. Upewnij się, że masz to gdzieś w settings.py:

    REST_FRAMEWORK = {
    
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework.authentication.TokenAuthentication',
            # ...
        ),
    
        # ...
    }
    
  3. Upewnij się, że masz prawidłowy token dla zalogowanego użytkownika. Jeśli nie masz tokena, dowiedz się, jak go uzyskać tutaj . Zasadniczo musisz wysłać POSTżądanie do widoku, który daje token, jeśli podasz poprawną nazwę użytkownika i hasło. Przykład:

    curl -X POST -d "user=Pepe&password=aaaa"  http://localhost:8000/
    
  4. Upewnij się, że widok, do którego próbujesz uzyskać dostęp, zawiera:

    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. Użyj curlteraz w ten sposób:

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

Przykład:

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

Jak można drukować request.user? Wygląda na to, że metoda POST widoku opartego na klasach nigdy nie jest przetwarzana. Gdzie jeszcze mogę spróbować wydrukować użytkownika?
— MadPhysicist

użytkownik musi być uwierzytelniony, aby mógł zostać ustawiony w obiekcie żądania. W przeciwnym razie po prostu drukuje anonimowego użytkownika. Jak uwierzytelniasz swojego użytkownika?
— sherelock

12

Jeśli bawisz się w wierszu poleceń (używając curl lub HTTPie itp.), Możesz użyć BasicAuthentication do przetestowania / użytkownika swojego 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',
        )
    }

Następnie możesz użyć curl

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

lub httpie (łatwiejsze dla oczu):

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

lub coś innego, jak Advanced Rest Client (ARC)


9

Ja też stanąłem w obliczu tego samego, odkąd przegapiłem dodawanie

authentication_classes = (TokenAuthentication)

w mojej klasie widoku interfejsu API.

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

Oprócz powyższego, musimy wyraźnie poinformować Django o uwierzytelnianiu w pliku settings.py.

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

3

Dodanie SessionAuthentication w settings.py wykona zadanie

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


3

W moim przypadku musiałem dołączyć do mojego nagłówka Authorization „JWT” zamiast „Bearer” lub „Token” na Django DRF. Potem zaczęło działać. np. -

Authorization: JWT asdflkj2ewmnsasdfmnwelfkjsdfghdfghdv.wlsfdkwefojdfgh


To samo tutaj. Używanie Next.JS z Django DRF jako zapleczem.
— kenneho

2

Miałem problem z listonoszem Dodaj to do nagłówków ... wprowadź opis obrazu tutaj


W moim przypadku nie zaznaczyłem checkboxa ... :) Dzięki, to dało mi wskazówkę
— Laxmikant

1

Ponieważ jest to logowanie sesyjne, musisz podać poświadczenia, więc 127.0.0:8000/admin zaloguj się jako administrator i zaloguj się później, będzie działać dobrze


1
Przepraszamy, ale na to pytanie udzielono już bardziej szczegółowych odpowiedzi niż twoje ...
— Muhammad Dyas Yaskur

To jest dla ludzi, którzy potrzebują szybkiego rozwiązania
— Aishwarya kabadi

1

Prawdopodobnie to zadziała

W settings.py

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

Dodaj to też

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

0

Jeśli używasz authentication_classes, powinieneś mieć is_activejak Truew Usermodelu, który może być Falsedomyślnie.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.