Django Rest Framework - ไม่ได้ระบุข้อมูลรับรองการพิสูจน์ตัวตน


110

ฉันกำลังพัฒนา API โดยใช้ Django Rest Framework ฉันกำลังพยายามสร้างรายการหรือสร้างออบเจ็กต์ "Order" แต่เมื่อฉันพยายามเข้าถึงคอนโซลทำให้เกิดข้อผิดพลาดนี้:

{"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."}

5
ลองนี้:curl -H "Authorization: Token 12383dcb52d627eabd39e7e88501e96a2sadc55" http://127.0.0.1:8000/api/orders/
คร

1
ข้อผิดพลาดเดียวกัน ไม่ได้ระบุข้อมูลรับรองการพิสูจน์ตัวตน
Marcos Aguayo

ในกรณีของฉันสิ่งนี้เกิดขึ้นเนื่องจากเพื่อนร่วมทีมเปลี่ยนผู้ใช้เป็นโหมดไม่ใช้งาน
Brock

ลองอ่านAuthenticationก่อน
สิ้นสุด

@endless คำถามคือเมื่อ 3 ปีที่แล้ว แก้ไขเรียบร้อยแล้ว
Marcos Aguayo

คำตอบ:


173

หากคุณใช้งาน Django บน Apache โดยใช้ mod_wsgi คุณต้องเพิ่ม

WSGIPassAuthorization On

ใน httpd.conf ของคุณ มิฉะนั้นส่วนหัวการให้สิทธิ์จะถูกตัดออกโดย mod_wsgi


1
ในกรณีที่คุณสงสัยว่าจะเขียนได้ที่ไหนให้ไปที่ลิงค์ stackoverflow.com/questions/49340534/…
user2858738

3
httpd.confสำหรับอูบุนตูดูเหมือนไม่มี เพื่อให้คุณมีการเพิ่มWSGIPassAuthorization Onใน/etc/apache2/apache2.conf
suhailvs

ฉันสับสนกับปัญหาที่คำขอของฉันจากบุรุษไปรษณีย์ทำงานจาก localhost ของฉัน แต่ไม่ใช่เมื่อส่งไปยังเซิร์ฟเวอร์ที่ใช้งานจริง ความคิดเห็นของคุณช่วยแก้ปัญหาของฉันได้
RommelTJ

แก้ไขปัญหาของฉันฉันสามารถรับข้อมูลผ่าน api บน localhost ของฉันได้ แต่เมื่อติดตั้งบนเซิร์ฟเวอร์ผ่าน https: // มันทำให้ฉันมีข้อผิดพลาดเดียวกัน
Mir Suhail

สิ่งนี้เป็นจริงเฉพาะในการผลิตหรือเพื่อการพัฒนาท้องถิ่นด้วยหรือไม่?
MadPhysicist

101

แก้ไขได้โดยเพิ่ม "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
ขอบคุณสำหรับการแก้ปัญหานี้! ฉันไม่เข้าใจว่าทำไมฉันไม่ได้รับ "ไม่ได้ระบุข้อมูลรับรองการตรวจสอบความถูกต้อง" เกิดข้อผิดพลาดเมื่อทำการร้องขอกับบุรุษไปรษณีย์ในขณะที่ฉันได้รับข้อผิดพลาดเมื่อลูกค้า Angular ของฉันส่งคำขอ ทั้งที่มีโทเค็นเดียวกันในส่วนหัวการอนุญาต ...
Sander Vanden Hautte

SessionAuthenticationจะเปิดใช้งานโดยค่าเริ่มต้นและทำงานร่วมกับคุกกี้เซสชันมาตรฐานดังนั้นจึงเป็นไปได้ว่าแอปพลิเคชัน Angular (หรือเฟรมเวิร์ก JS อื่น) ของคุณทำงานได้เนื่องจากการตรวจสอบสิทธิ์เซสชันเริ่มต้น
Kevin Brown

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
Nick T

16

เพียงสำหรับคนอื่น ๆ ที่เชื่อมโยงไปถึงขึ้นที่นี่ด้วยข้อผิดพลาดเดียวกันปัญหานี้สามารถเกิดขึ้นได้ถ้าคุณrequest.userมีAnonymousUserและไม่ใช้สิทธิที่มีอำนาจจริงในการเข้าถึงของ URL คุณสามารถดูได้โดยการพิมพ์ค่าของrequest.user. หากเป็นผู้ใช้ที่ไม่ระบุชื่อขั้นตอนเหล่านี้อาจช่วยได้:

  1. ตรวจสอบให้แน่ใจว่าคุณมี 'rest_framework.authtoken'ในในของคุณINSTALLED_APPSsettings.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

12

หากคุณกำลังเล่นในบรรทัดคำสั่ง (โดยใช้ 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)


9

ฉันก็เผชิญเช่นเดียวกันตั้งแต่ฉันพลาดการเพิ่ม

authentication_classes = (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',
   )
}

5

สำหรับฉันฉันต้องนำหน้าส่วนหัวการอนุญาตด้วย "JWT" ​​แทน "Bearer" หรือ "Token" บน Django DRF จากนั้นก็เริ่มทำงาน เช่น -

Authorization: JWT asdflkj2ewmnsasdfmnwelfkjsdfghdfghdv.wlsfdkwefojdfgh


เหมือนกันที่นี่ ใช้ Next.JS กับ Django DRF เป็นแบ็กเอนด์
kenneho

ตกลง ลอง django กับ react เป็นครั้งแรกและคำตอบของคุณช่วยฉันได้
Rahul


2

ฉันมีปัญหากับบุรุษไปรษณีย์เพิ่มสิ่งนี้ในส่วนหัว ... ใส่คำอธิบายภาพที่นี่


ในกรณีของฉันฉันไม่ได้เลือกช่องทำเครื่องหมาย ... :) ขอบคุณสิ่งนี้ทำให้ฉันได้เบาะแส
Laxmikant

2

อาจจะได้ผล

ใน settings.py

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

เพิ่มสิ่งนี้ด้วย

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

1

เนื่องจากเป็นการเข้าสู่ระบบเซสชันดังนั้นคุณจึงต้องให้ข้อมูลรับรองแก่คุณดังนั้น 127.0.0:8000/admin ผู้ดูแลระบบและเข้าสู่ระบบในภายหลังจึงจะทำงานได้ดี


1
ขออภัยคำถามนี้มีคำตอบที่มีรายละเอียดมากกว่าของคุณอยู่แล้ว ...
Muhammad Dyas Yaskur

สำหรับผู้ที่ต้องการการแก้ปัญหาอย่างรวดเร็ว
Aishwarya kabadi

0

หากคุณกำลังใช้authentication_classesแล้วคุณควรจะมีis_activeเป็นTrueในUserรูปแบบซึ่งอาจจะเป็นFalseไปโดยปริยาย


คลาสการพิสูจน์ตัวตนคืออะไร?
แซม
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.