Django:未提供身份验证凭据

2024-06-25 22:48:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经在这个主题上找到了十几个类似的SO帖子,并将他们的解决方案应用到了我所理解的最好的地方,但它们对我来说并不管用。为什么我在使用AJAX补丁请求命中Django Rest Framework端点之后得到这个错误detail: "Authentication credentials were not provided."谢谢你的帮助!

一些细节

  • 标题告诉我“状态代码:401未授权”
  • 我在本地主机开发服务器(Postgres)上
  • 在这个应用程序中的其他应用程序上运行的任何其他django表单或ajax(get和Posts)请求都不会出现此错误。在
  • 这是我第一次尝试修补程序请求
  • 最终,一旦这个Ajax补丁请求起作用,我只想将bookid添加到api.BookGroup模型中的ManyToManyFieldbooks字段中
  • 我试着按照类似帖子中的建议调整设置.py允许正确的身份验证和权限方法。在
  • 关于the DRF documentation,我还将权限类更改为permission_classes = (IsAuthenticated,),如果我在发出请求时登录,则允许进行修补程序请求(是的,我肯定已登录)
  • ajax头中的表单数据表明我正确地传递了CSRF令牌和适当的变量:

    csrfmiddlewaretoken: UjGnVfQTfcmkZKtWjI0m89zlAJqR0wMmUVdh1T1JaiCdyRe2TiW3LPWt
    bookid: 1
    bookgroupid: 71
    

AJAX

^{pr2}$

网址.py

from django.urls import path, include
from django.conf.urls import url
from . import views
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('', include(router.urls)),
    url(r'bookgroups/\d+/$', views.BookGroupUpdateSet.as_view()),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

视图.py

from rest_framework.generics import ListAPIView, DestroyAPIView, UpdateAPIView, RetrieveAPIView
from rest_framework.authentication import TokenAuthentication, SessionAuthentication, BasicAuthentication
from rest_framework.authtoken.serializers import AuthTokenSerializer
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.permissions import IsAuthenticatedOrReadOnly, IsAuthenticated
from . import serializers, models, permissions

class BookGroupUpdateSet(UpdateAPIView):
    queryset = models.BookGroup.objects.all()
    model = models.BookGroup
    serializer_class = serializers.BookGroupUpdateSerializer

    def patch(self, request, pk=None):
        permission_classes = (IsAuthenticated,)
        authentication_classes = (TokenAuthentication,)
        bookid = request.Patch['bookid']
        bookgroupid = request.Patch['bookgroupid']
        print("...Print stuff...")

设置.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'authenticate',
    'api',
    'rest_framework',
    'rest_framework.authtoken',
]

AUTH_USER_MODEL = "api.UserProfile"

REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
   'rest_framework.authentication.TokenAuthentication',
   'rest_framework.authentication.SessionAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
    # 'rest_framework.permissions.AllowAny',  # I've tried this too, same results
    'rest_framework.permissions.IsAuthenticated',
)
}

Tags: djangofrompyimportrestapipermissionsauthentication
2条回答

一旦您的API视图需要身份验证才能被访问,您需要向请求头提供Authorization头: Authorization: Token <token>

那么,你怎么得到这个代币?根据DRF文档,您需要为数据库中的每个用户创建一个令牌。因此,无论何时创建新用户,您都必须手动执行此操作,或者您可以通过导入并使用以下命令来使用DRF令牌身份验证视图:

from rest_framework.authtoken.views import ObtainAuthToken

但我建议您使用django rest auth应用程序,这样可以简化DRF中的令牌身份验证过程。 https://django-rest-auth.readthedocs.io/en/latest/

对于Django Rest Framework视图,您不使用CSRF标记,而是使用自定义的DRF标记(这就是rest_framework.authtoken的用途)。创建新用户时,必须创建他的令牌,如下所示:

def create(self, validated_data):
    from rest_framework.authtoken.models import Token

    try:
        user = models.User.objects.get(email=validated_data.get('email'))
    except User.DoesNotExist:
        user = models.User.objects.create(**validated_data)

        user.set_password(user.password)
        user.save()
        Token.objects.create(user=user) #    -> Token creation

        return user
    else:
        raise CustomValidation('eMail already in use', 'email', status_code=status.HTTP_409_CONFLICT)

然后,您必须为用户获取令牌,并用密钥名Authorization和值Token <token>在头中发送它。在

相关问题 更多 >