Подтвердить что ты не робот

Django Rest Framework - учетные данные аутентификации не были предоставлены

Я разрабатываю 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,)

Serializer:

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."}
4b9b3361

Ответ 1

Решено, добавив "DEFAULT_AUTHENTICATION_CLASSES" в мои settings.py

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

Ответ 2

Если вы запускаете Django на Apache, используя mod_wsgi, вы должны добавить

WSGIPassAuthorization On

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

Ответ 3

Это поможет мне без "DEFAULT_PERMISSION_CLASSES" в моих settings.py

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

Ответ 4

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

  • Убедитесь, что у вас 'rest_framework.authtoken' в INSTALLED_APPS в settings.py.

  • Убедитесь, что у вас есть это где-то в settings.py:

    REST_FRAMEWORK = {
    
        'DEFAULT_AUTHENTICATION_CLASSES': (
            'rest_framework.authentication.TokenAuthentication',
            # ...
        ),
    
        # ...
    }
    
  • Убедитесь, что у пользователя есть правильный токен. Если у вас нет токена, узнайте, как его получить здесь. В принципе, вам нужно сделать запрос POST к представлению, которое даст вам токен, если вы укажете правильное имя пользователя и пароль. Пример:

    curl -X POST -d "user=Pepe&password=aaaa"  http://localhost:8000/
    
  • Убедитесь, что представление, к которому вы пытаетесь получить доступ, имеет следующие значения:

    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,) 
        # ...
    
  • Используйте 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"

Ответ 5

Если вы играете в командной строке (используя 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

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)