Django Rest Framework - credenciais de autenticação não foram fornecidas


98

Estou desenvolvendo uma API usando Django Rest Framework. Estou tentando listar ou criar um objeto "Pedido", mas quando tento acessar o console, vejo este erro:

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

Visualizações:

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

Serializer:

class OrderSerializer(serializers.HyperlinkedModelSerializer):

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

E meus URLs:

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

E então estou usando este comando no console:

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

E o erro diz:

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

5
Experimente:curl -H "Authorization: Token 12383dcb52d627eabd39e7e88501e96a2sadc55" http://127.0.0.1:8000/api/orders/
— cor

1
Mesmo erro. Credenciais de autenticação não fornecidas
— Marcos Aguayo

No meu caso, isso aconteceu devido a um colega de equipe mudar o usuário para o modo inativo.
— Brock

Tente ler a autenticação primeiro.
— infinito em

@endless A questão foi há 3 anos. Já está resolvido
— Marcos Aguayo

Respostas:


159

Se você está executando o Django no Apache usando mod_wsgi, você deve adicionar

WSGIPassAuthorization On

em seu httpd.conf. Caso contrário, o cabeçalho de autorização será removido por mod_wsgi.


1
Caso você esteja se perguntando onde escrever isso, siga o link. stackoverflow.com/questions/49340534/…
— user2858738

1
para o Ubuntu parece que não httpd.conf. então você tem que adicionar WSGIPassAuthorization Onem/etc/apache2/apache2.conf
— suhailvs

Fiquei confuso com um problema em que minhas solicitações do Postman estavam funcionando no meu host local, mas não quando enviadas para o servidor ativo. Seu comentário resolveu meu problema.
— RommelTJ de

Resolvido meu problema, consegui obter dados via api em meu localhost, mas quando implantado no servidor via https: // estava dando o mesmo erro.
— Mir Suhail

Isso é válido apenas para a produção ou também para o desenvolvimento local?
— MadPhysicist

93

Resolvido ao adicionar "DEFAULT_AUTHENTICATION_CLASSES" às minhas configurações.py

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

Pensei que tivesse feito isso, mas adicionei 'rest_framework.authentication.TokenAuthentication'ao em DEFAULT_PERMISSION_CLASSESvez deDEFAULT_AUTHENTICATION_CLASSES
— netigger

4
Obrigado por esta solução! Não entendo, no entanto, por que não recebi a mensagem "Credenciais de autenticação não fornecidas". erro ao fazer a solicitação com o Postman, ao passo que recebi o erro quando meu cliente Angular fez solicitações. Ambos com o mesmo token no cabeçalho de autorização ...
— Sander Vanden Hautte

SessionAuthenticationestá habilitado por padrão e funciona com os cookies de sessão padrão, portanto, é provável que seu aplicativo Angular (ou outra estrutura JS) estivesse funcionando por causa da autenticação de sessão padrão.
— Kevin Brown

27

Isso me ajuda sem "DEFAULT_PERMISSION_CLASSES" em minhas configurações.py

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

3
O SessionAuthenticationfoi o que fixa-lo para mim
— Caleb_Allen

Consertou para mim também. Gostaria de saber por que o tutorial do Django sobre isso não menciona isso. Veja django-rest-framework.org/tutorial/quickstart .
— Nick T

15

Apenas para outras pessoas que chegam aqui com o mesmo erro, esse problema pode surgir se você request.userfor AnonymousUsere não o usuário correto que está realmente autorizado a acessar o URL. Você pode ver isso imprimindo o valor de request.user. Se for realmente um usuário anônimo, estas etapas podem ajudar:

  1. Certifique-se de que você tem 'rest_framework.authtoken'na INSTALLED_APPSsua settings.py.

  2. Certifique-se de ter isso em algum lugar em settings.py:

    REST_FRAMEWORK = {
    
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework.authentication.TokenAuthentication',
            # ...
        ),
    
        # ...
    }
  3. Certifique-se de ter o token correto para o usuário que está conectado. Se você não tiver o token, saiba como obtê-lo aqui . Basicamente, você precisa fazer uma POSTsolicitação para uma visualização que fornece o token se você fornecer o nome de usuário e a senha corretos. Exemplo:

    curl -X POST -d "user=Pepe&password=aaaa"  http://localhost:8000/
  4. Certifique-se de que a vista da propriedade que você está tentando acessar tenha estes:

    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. Use curlagora desta forma:

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

Exemplo:

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

Como se pode imprimir request.user? Parece que o método POST de uma visão baseada em classe nunca está sendo processado. Onde mais posso tentar imprimir o usuário?
— MadPhysicist

o usuário deve ser autenticado para poder ser definido no objeto de solicitação. Caso contrário, ele apenas imprime usuário anônimo. Como você está autenticando seu usuário?
— sherelock

11

Se você estiver brincando na linha de comando (usando curl ou HTTPie etc), você pode usar BasicAuthentication para testar / usar sua 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',
        )
    }

Você pode então usar curl

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

ou httpie (é mais fácil para os olhos):

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

ou algo como Cliente de Repouso Avançado (ARC)


8

Eu também enfrentei o mesmo desde que deixei de adicionar

authentication_classes = (TokenAuthentication)

na minha classe de visualização da API.

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

Além do acima, precisamos informar explicitamente ao Django sobre a autenticação no arquivo settings.py.

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

3

Adicionar SessionAuthentication em settings.py fará o trabalho

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


1

Como é o login da sessão, você precisa fornecer as credenciais, então faça o 127.0.0:8000/admin administrador e faça o login mais tarde, ele funcionará bem


1
Desculpe, mas esta pergunta já foi respondida com mais detalhes do que a sua ...
— Muhammad Dyas Yaskur

Isso é para pessoas que precisam de uma solução rápida
— Aishwarya kabadi

1

Para mim, tive que preceder meu cabeçalho de autorização com "JWT" ​​em vez de "Bearer" ou "Token" no Django DRF. Então começou a funcionar. por exemplo -

Authorization: JWT asdflkj2ewmnsasdfmnwelfkjsdfghdfghdv.wlsfdkwefojdfgh


0

Se você estiver usando authentication_classes, então você deve ter is_activecomo Trueno Usermodelo, que pode ser Falsepor padrão.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.