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."}
python
django
django-rest-framework
Marcos Aguayo
źródło
źródło
curl -H "Authorization: Token 12383dcb52d627eabd39e7e88501e96a2sadc55" http://127.0.0.1:8000/api/orders/
Odpowiedzi:
Jeśli używasz Django na Apache używając mod_wsgi, musisz dodać
w twoim httpd.conf. W przeciwnym razie nagłówek autoryzacji zostanie usunięty przez mod_wsgi.
źródło
httpd.conf
. więc trzeba dodaćWSGIPassAuthorization On
w/etc/apache2/apache2.conf
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' ), }
źródło
'rest_framework.authentication.TokenAuthentication'
sięDEFAULT_PERMISSION_CLASSES
zamiastDEFAULT_AUTHENTICATION_CLASSES
SessionAuthentication
jest 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.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 }
źródło
SessionAuthentication
właśnie rozwiązało problemTylko dla innych ludzi lądowania tutaj z tego samego błędu, to problem może pojawić się jeśli
request.user
jestAnonymousUser
, 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:Upewnij się, że
'rest_framework.authtoken'
wINSTALLED_APPS
na swójsettings.py
.Upewnij się, że masz to gdzieś w
settings.py
:REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.TokenAuthentication', # ... ), # ... }
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/
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,) # ...
Użyj
curl
teraz 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"
źródło
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?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)
źródło
Ja też stanąłem w obliczu tego samego, odkąd przegapiłem dodawanie
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', ) }
źródło
Dodanie SessionAuthentication w settings.py wykona zadanie
REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.SessionAuthentication', ), }
źródło
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
źródło
Miałem problem z listonoszem Dodaj to do nagłówków ...
źródło
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źródło
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', ) ... .. }
źródło
Jeśli używasz
authentication_classes
, powinieneś miećis_active
jakTrue
wUser
modelu, który może byćFalse
domyślnie.źródło