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

99

Je développe une API en utilisant Django Rest Framework. J'essaye de lister ou de créer un objet "Order", mais lorsque j'essaye d'accéder à la console, cela me donne cette erreur:

{"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."}
Marcos Aguayo
la source
5
Essayez ceci:curl -H "Authorization: Token 12383dcb52d627eabd39e7e88501e96a2sadc55" http://127.0.0.1:8000/api/orders/
cor
1
Même erreur. Les informations d'authentification n'ont pas été fournies
Marcos Aguayo
Dans mon cas, cela s'est produit en raison d'un coéquipier qui a basculé l'utilisateur en mode inactif.
Brock
Essayez d'abord de lire Authentification .
interminable le
@endless La question remonte à 3 ans. C'est déjà résolu
Marcos Aguayo

Réponses:

160

Si vous exécutez Django sur Apache en utilisant mod_wsgi, vous devez ajouter

WSGIPassAuthorization On

dans votre httpd.conf. Sinon, l'en-tête d'autorisation sera supprimé par mod_wsgi.

Robert Kovac
la source
1
Au cas où vous vous demandez où écrire ceci, suivez le lien. stackoverflow.com/questions/49340534/…
user2858738
1
pour ubuntu il ne semble pas httpd.conf. de sorte que vous devez ajouter WSGIPassAuthorization Onà/etc/apache2/apache2.conf
suhailvs
J'ai été confus par un problème où mes demandes de Postman fonctionnaient à partir de mon hôte local, mais pas lorsqu'elles étaient envoyées au serveur en direct. Votre commentaire a résolu mon problème.
RommelTJ
Résolu Mon problème, j'ai pu obtenir des données via api sur mon hôte local, mais une fois déployé sur le serveur via https: //, cela me donnait la même erreur.
Mir Suhail le
Est-ce vrai uniquement pour la production ou pour le développement local?
MadPhysicist
93

Résolu en ajoutant "DEFAULT_AUTHENTICATION_CLASSES" à mes paramètres.py

REST_FRAMEWORK = {
   'DEFAULT_AUTHENTICATION_CLASSES': (
       'rest_framework.authentication.TokenAuthentication',
   ),
   'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAdminUser'
   ),
}
Marcos Aguayo
la source
Je pensais avoir fait cela, mais j'avais ajouté 'rest_framework.authentication.TokenAuthentication'au DEFAULT_PERMISSION_CLASSESlieu deDEFAULT_AUTHENTICATION_CLASSES
netigger
4
Merci pour cette solution! Je ne comprends cependant pas pourquoi je n'ai pas obtenu le message "Les informations d'authentification n'ont pas été fournies". erreur lors de la demande avec Postman, alors que je l'ai fait obtenir l'erreur lorsque mon client angulaire a fait des demandes. Tous les deux avec le même jeton dans l'en-tête d'autorisation ...
Sander Vanden Hautte
SessionAuthenticationest activé par défaut et fonctionne avec les cookies de session standard, il est donc probable que votre application Angular (ou un autre framework JS) fonctionnait en raison de l'authentification de session par défaut.
Kevin Brown le
27

Cela m'aide sans "DEFAULT_PERMISSION_CLASSES" dans mes paramètres.py

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ),
    'PAGE_SIZE': 10
}
uestcfei
la source
3
Le SessionAuthenticationétait ce qu'il fixe pour moi
Caleb_Allen
Correction de ça pour moi aussi. Je me demande pourquoi le tutoriel Django à ce sujet ne le mentionne pas. Voir django-rest-framework.org/tutorial/quickstart .
Nick T
15

Juste pour d' autres personnes débarquant ici avec la même erreur, ce problème peut survenir si votre request.userest AnonymousUseret non l'utilisateur droit qui est effectivement autorisé à accéder à l'URL. Vous pouvez le voir en imprimant la valeur de request.user. S'il s'agit bien d'un utilisateur anonyme, ces étapes peuvent vous aider:

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

  2. Assurez-vous que vous avez ceci quelque part dans settings.py:

    REST_FRAMEWORK = {
    
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework.authentication.TokenAuthentication',
            # ...
        ),
    
        # ...
    }
  3. Assurez-vous que vous disposez du bon jeton pour l'utilisateur connecté. Si vous ne disposez pas du jeton, découvrez comment l'obtenir ici . Fondamentalement, vous devez faire une POSTdemande à une vue qui vous donne 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 contient les éléments suivants:

    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 curlmaintenant 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"
sherelock
la source
Comment imprimer request.user? Il semble que la méthode POST d'une vue basée sur les classes ne soit jamais traitée. Où puis-je essayer d'imprimer l'utilisateur?
MadPhysicist
l'utilisateur doit être authentifié pour pouvoir être défini dans l'objet de requête. Sinon, il imprime simplement l'utilisateur anonyme. Comment authentifiez-vous votre utilisateur?
sherelock
11

Si vous jouez dans la ligne de commande (en utilisant 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)

lukeaus
la source
8

J'ai aussi fait face à la même chose depuis que j'ai manqué d'ajouter

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 informer explicitement Django de l' authentification dans le fichier settings.py.

REST_FRAMEWORK = {
   'DEFAULT_AUTHENTICATION_CLASSES': (
   'rest_framework.authentication.TokenAuthentication',
   )
}
prashant
la source
3

L'ajout de SessionAuthentication dans settings.py fera le travail

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

Pritam Roy
la source
1

Comme il s'agit d'une session de connexion, vous devez donc fournir vos informations d'identification, alors 127.0.0:8000/admin admin et connectez-vous plus tard, cela fonctionnera bien

Aishwarya kabadi
la source
1
Désolé, mais cette question a déjà
reçu une
Ceci est pour les personnes qui ont besoin d'une solution rapide
Aishwarya kabadi
1

Pour moi, j'ai dû ajouter à mon en-tête d'autorisation "JWT" ​​au lieu de "Bearer" ou "Token" sur Django DRF. Ensuite, cela a commencé à fonctionner. par exemple -

Authorization: JWT asdflkj2ewmnsasdfmnwelfkjsdfghdfghdv.wlsfdkwefojdfgh

kiko carisse
la source
0

Si vous utilisez, authentication_classesvous devriez avoir is_activecomme Truedans le Usermodèle, ce qui peut être Falsepar défaut.

Piyush Jaiswal
la source