web-dev-qa-db-fra.com

Django Rest Framework - Les informations d'authentification n'ont pas été fournies.

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."}
70
Marcos Aguayo

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'
   ),
}
69
Marcos Aguayo

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.

125
Robert Kovac

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
}
22
uestcfei

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:

  1. Assurez-vous que vous avez 'rest_framework.authtoken' dans INSTALLED_APPS dans votre settings.py.

  2. Assurez-vous de l'avoir quelque part dans settings.py:

    REST_FRAMEWORK = {
    
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework.authentication.TokenAuthentication',
            # ...
        ),
    
        # ...
    }
    
  3. 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/
    
  4. 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,) 
        # ...
    
  5. 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"
12
sherelock

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)

8
lukeaus

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',
   )
}
5
prashant

Ajouter SessionAuthentication dans settings.py fera le travail

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

2
Pritam Roy