Django Rest Framework - облікові дані для автентифікації не надано


105

Я розробляю API, використовуючи Django Rest Framework. Я намагаюся зробити список або створити об'єкт "Замовлення", але коли я намагаюся отримати доступ до консолі, мені видається така помилка:

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

Перегляди:

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

Серіалізатор:

class OrderSerializer(serializers.HyperlinkedModelSerializer):

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

І мої 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)),
)

І тоді я використовую цю команду в консолі:

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

І помилка каже:

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

5
Спробуйте це:curl -H "Authorization: Token 12383dcb52d627eabd39e7e88501e96a2sadc55" http://127.0.0.1:8000/api/orders/
cor

1
Та сама помилка. Аутентифікаційні дані не були надані
Маркос Агуайо

У моєму випадку це сталося через переключення користувача в неактивний режим.
Brock

Спробуйте прочитати автентифікацію спочатку.
нескінченні

@endless Питання було 3 роки тому. Це вже вирішено
Маркос Агуайо

Відповіді:


167

Якщо ви запускаєте Django на Apache за допомогою mod_wsgi, вам потрібно додати

WSGIPassAuthorization On

у вашому httpd.conf. В іншому випадку заголовок авторизації буде видалено mod_wsgi.


1
Якщо вам цікаво, де це написати, перейдіть за посиланням. stackoverflow.com/questions/49340534 / ...
user2858738

2
для ubuntu, здається, немає httpd.conf. так що ви повинні додати WSGIPassAuthorization Onв/etc/apache2/apache2.conf
suhailvs

Мене збентежила проблема, коли мої запити від Postman працювали з мого localhost, але не під час надсилання на живий сервер. Ваш коментар вирішив мою проблему.
RommelTJ

Вирішено мою проблему, я зміг отримати дані через api на своєму локальному хості, але при розгортанні на сервері через https: // це дало мені таку ж помилку.
Mir Suhail

Це правда лише у виробництві чи для місцевого розвитку?
MadPhysicist

97

Вирішено шляхом додавання "DEFAULT_AUTHENTICATION_CLASSES" до мого settings.py

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

Думав , що я зробив це, але я додав 'rest_framework.authentication.TokenAuthentication'до DEFAULT_PERMISSION_CLASSESаDEFAULT_AUTHENTICATION_CLASSES
netigger

4
Дякую за це рішення! Однак я не розумію, чому я не отримав "Повноваження для автентифікації не були надані". Помилка при виконанні запиту з Листоноша, в той час як я зробив отримую помилку , коли мій клієнт зробив Кутова запити. Обидва з однаковим
жетоном

SessionAuthenticationУвімкнено за замовчуванням і працює зі стандартними файлами cookie сеансу, тому, ймовірно, програма Angular (або інша структура JS) працювала через автентифікацію сеансу за замовчуванням.
Кевін Браун,

29

Це допоможе мені без "DEFAULT_PERMISSION_CLASSES" у моєму settings.py

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

3
Для SessionAuthenticationмене це було виправлено
Caleb_Allen

Виправили це і для мене. Цікаво, чому підручник з Django про це не згадує. Див. Django-rest-framework.org/tutorial/quickstart .
Нік Т.

15

Просто для інших людей, які приземляються сюди з тією ж помилкою, ця проблема може виникнути, якщо ви request.userє AnonymousUserа не правильним користувачем, який насправді має право отримати доступ до URL-адреси. Ви можете переконатися в цьому, надрукувавши значення request.user. Якщо це справді анонімний користувач, ці кроки можуть допомогти:

  1. Переконайтеся, що 'rest_framework.authtoken'в INSTALLED_APPSу вашому settings.py.

  2. Переконайтеся, що у вас це є десь у settings.py:

    REST_FRAMEWORK = {
    
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework.authentication.TokenAuthentication',
            # ...
        ),
    
        # ...
    }
    
  3. Переконайтеся, що у вас є правильний маркер для користувача, який увійшов до системи. Якщо у вас немає маркера, дізнайтеся, як його отримати тут . В основному, вам потрібно зробити POSTзапит на подання, яке надає вам маркер, якщо ви вказали правильне ім’я користувача та пароль. Приклад:

    curl -X POST -d "user=Pepe&password=aaaa"  http://localhost:8000/
    
  4. Переконайтеся, що подання, до якого ви намагаєтесь отримати доступ, має такі:

    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. Використовуйте curlзараз таким чином:

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

Приклад:

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

Як можна друкувати request.user? Здається, що метод POST для подання на основі класу ніколи не обробляється. Де ще я можу спробувати роздрукувати користувача?
MadPhysicist

користувач повинен бути аутентифікований, щоб мати можливість встановлюватися в об'єкт запиту. В іншому випадку він просто друкує анонімного користувача. Як ви проходите аутентифікацію свого користувача?
sherelock

11

Якщо ви граєтесь у командному рядку (за допомогою curl, HTTPie тощо), ви можете використовувати BasicAuthentication для тестування / користування вашим 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',
        )
    }

Потім можна використовувати завивку

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

або httpie (це легше на очах):

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

або щось інше, як Advanced Rest Client (ARC)


9

Я теж стикався з тим самим, оскільки пропустив додавання

автентифікаційні_класи = (TokenAuthentication)

у моєму класі перегляду API.

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

На додаток до вищезазначеного, нам потрібно чітко повідомити Django про аутентифікацію у файлі settings.py.

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

3

Додавання SessionAuthentication в settings.py зробить свою роботу

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


3

Для мене мені довелося до мого заголовка авторизації додавати "JWT" ​​замість "Bearer" або "Token" на Django DRF. Потім воно почало працювати. наприклад -

Authorization: JWT asdflkj2ewmnsasdfmnwelfkjsdfghdfghdv.wlsfdkwefojdfgh


Те ж саме. Використання Next.JS з Django DRF як серверною базою.
kenneho

2

У мене була проблема з листоношею. Додайте це до заголовків ... введіть тут опис зображення


У моєму випадку я не встановив прапорець ... :) Дякую, це дало мені підказку
Laxmikant

1

Оскільки це сеанс Логін, тож вам потрібно надати свої облікові дані, так що 127.0.0:8000/admin адміністратор і авторизація пізніше це буде працювати нормально


1
Вибачте, але на це питання вже відповіли більш докладно, ніж ваше ...
Мухаммад Дьяс Яскур,

Це для людей, яким потрібне швидке рішення
Айшварія кабаді,

1

Можливо, це могло спрацювати

У settings.py

SIMPLE_JWT = {
     ....
     ...
     # Use JWT 
     'AUTH_HEADER_TYPES': ('JWT',),
     # 'AUTH_HEADER_TYPES': ('Bearer',),
     ....
     ...
}

Додайте і це

REST_FRAMEWORK = {
    ....
    ...
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    )
    ...
    ..
}

0

Якщо ви використовуєте, authentication_classesтоді ви повинні мати is_activeяк Trueу Userмоделі, яка може бути Falseза замовчуванням.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.