Je développe une API en utilisant Django Rest Framework. J'essaie de répertorier ou de créer un objet "Order", mais lorsque j'essaie d'accéder à la console, cette erreur se produit:
{"detail": "Authentication credentials were not provided."}
Vues:
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,)
Sérialiseur:
class OrderSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Order
fields = ('field1', 'field2')
Et mes 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)),
)
Et puis j'utilise cette commande dans la console:
curl -X GET http://127.0.0.1:8000/api/orders/ -H 'Authorization: Token 12383dcb52d627eabd39e7e88501e96a2sadc55'
Et l'erreur dit:
{"detail": "Authentication credentials were not provided."}
Résolu en ajoutant "DEFAULT_AUTHENTICATION_CLASSES" à mon settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAdminUser'
),
}
Si vous êtes runnig Django sur Apache avec mod_wsgi, vous devez ajouter
WSGIPassAuthorization On
dans votre httpd.conf. Sinon l'en-tête d'autorisation sera supprimé par mod_wsgi.
Cela m'aide sans "DEFAULT_PERMISSION_CLASSES" dans mon fichier settings.py.
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
'PAGE_SIZE': 10
}
Juste pour les autres personnes qui débarquent ici avec la même erreur, ce problème peut survenir si votre request.user
est AnonymousUser
et non le bon utilisateur qui est réellement autorisé à accéder à l’URL. Vous pouvez voir cela en imprimant la valeur de request.user
. S'il s'agit bien d'un utilisateur anonyme, ces étapes pourraient vous aider:
Assurez-vous que vous avez 'rest_framework.authtoken'
dans INSTALLED_APPS
dans votre settings.py
.
Assurez-vous de l'avoir quelque part dans settings.py
:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
# ...
),
# ...
}
Assurez-vous que vous avez le bon jeton pour l'utilisateur connecté. Si vous ne le possédez pas, découvrez comment l'obtenir ici . Fondamentalement, vous devez envoyer une requête POST
à une vue qui vous donnera le jeton si vous fournissez le nom d'utilisateur et le mot de passe corrects. Exemple:
curl -X POST -d "user=Pepe&password=aaaa" http://localhost:8000/
Assurez-vous que la vue à laquelle vous essayez d'accéder a:
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,)
# ...
Utilisez curl
maintenant de cette façon:
curl -X (your_request_method) -H "Authorization: Token <your_token>" <your_url>
Exemple:
curl -X GET http://127.0.0.1:8001/expenses/ -H "Authorization: Token 9463b437afdd3f34b8ec66acda4b192a815a15a8"
Si vous jouez dans la ligne de commande (avec curl, ou HTTPie, etc.), vous pouvez utiliser BasicAuthentication pour tester/utiliser votre 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',
)
}
Vous pouvez ensuite utiliser curl
curl --user user:password -X POST http://example.com/path/ --data "some_field=some data"
ou httpie (c'est plus facile pour les yeux):
http -a user:password POST http://example.com/path/ some_field="some data"
ou quelque chose d'autre comme Advanced Rest Client (ARC)
Moi aussi j'ai fait face au même depuis que j'ai raté l'ajout
authentication_classes = (TokenAuthentication)
dans ma classe de vue API.
class ServiceList(generics.ListCreateAPIView):
authentication_classes = (SessionAuthentication, BasicAuthentication, TokenAuthentication)
queryset = Service.objects.all()
serializer_class = ServiceSerializer
permission_classes = (IsAdminOrReadOnly,)
En plus de ce qui précède, nous devons explicitement dire Django à propos de Authentification dans le fichier settings.py.
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
)
}
Ajouter SessionAuthentication dans settings.py fera le travailREST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.SessionAuthentication', ), }