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.