简体   繁体   English

Django:未提供身份验证凭据

[英]Django: Authentication credentials were not provided

I've pulled up a dozen similar SO posts on this topic, and have implemented their solutions to the best that I have understood them, yet they haven't worked for me. 我在这个主题上搜集了十几个类似的SO帖子,并以我所理解的最好的方式实施了他们的解决方案,但它们并没有为我工作。 Why am I getting this error detail: "Authentication credentials were not provided." 为什么得到此错误 detail: "Authentication credentials were not provided." after using an AJAX Patch request to hit my Django Rest Framework endpoint? 使用AJAX修补程序请求击中Django Rest Framework端点后? I appreciate your help! 我感谢您的帮助!

Some Details 一些细节

  • The header tells me "Status Code: 401 Unauthorized" 标头告诉我“状态码:未经授权的401”
  • I'm on my localHost development server (Postgres) 我在我的localHost开发服务器(Postgres)上
  • I don't get this error with any other django forms or ajax (Get and Posts) requests running on other apps within this application. 我在此应用程序内其他应用程序上运行的其他任何django表单或ajax(获取和发布)请求中均未收到此错误。
  • This is the first time I'm attempting a PATCH request 这是我第一次尝试PATCH请求
  • Ultimately, Once this Ajax Patch request works I, simply want to add bookid to the ManyToManyField books field in the api.BookGroup model 最终,一旦这个Ajax Patch请求bookid ,我只想将bookid添加到api.BookGroup模型中的ManyToManyField books字段中
  • I've tried to follow the suggestions in similar posts which recommend adjusting the settings.py to allow the right authentication and permission methods. 我尝试遵循类似文章中的建议,这些建议建议调整settings.py以允许使用正确的身份验证和权限方法。
  • referring to the DRF documentation , I've also changed the permission classes to permission_classes = (IsAuthenticated,) which should allow a patch request if I'm logged in when making the request (and yes, I am definitely logged in) 参考DRF文档 ,我还将权限类别更改为permission_classes = (IsAuthenticated,) ,如果我在发出请求时登录,则应允许补丁请求(是的,我肯定已登录)
  • The form data in the ajax header shows that I am correctly passing the CSRF token and the proper variables: Ajax标头中的表单数据显示我正确地传递了CSRF令牌和适当的变量:

     csrfmiddlewaretoken: UjGnVfQTfcmkZKtWjI0m89zlAJqR0wMmUVdh1T1JaiCdyRe2TiW3LPWt bookid: 1 bookgroupid: 71 

AJAX AJAX

function AddToBookGroup(bookgroupid,bookid){
 $.ajax({
    type: "PATCH",
    url: '/api/bookgroups/'+bookgroupid+'/',
    data: {
        csrfmiddlewaretoken: window.CSRF_TOKEN,
        bookid: bookid,
        bookgroupid: bookgroupid
        }, 
    success: function(data){
        console.log( 'success, server says '+data);  
    }
 });
}

URLS.py URLS.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)

VIEWS.py VIEWS.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...")

SETTINGS.py SETTINGS.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',
)
}

Once your API View requires authentication for being accessed, you need to provide to the request's header the Authorization header: Authorization: Token <token> 一旦您的API视图要求进行身份验证才能访问,则需要向请求的标头提供Authorization标头: Authorization: Token <token>

So, how do you get this Token? 那么,您如何获得此令牌? According to the DRF documentation, You need to create a token for each user in your database. 根据DRF文档,您需要为数据库中的每个用户创建一个令牌。 So, you have to do manually whenever a new user is created or you can use the DRF Token authentication views by importing and using: 因此,无论何时创建新用户,您都必须手动执行操作,或者可以通过导入和使用DRF令牌认证视图来使用:

from rest_framework.authtoken.views import ObtainAuthToken

But I suggest You use the django-rest-auth app, It makes easier the Token authentication process in DRF. 但是我建议您使用django-rest-auth应用程序,它可以简化DRF中的令牌身份验证过程。 https://django-rest-auth.readthedocs.io/en/latest/ https://django-rest-auth.readthedocs.io/en/latest/

With Django Rest Framework views, you don't use CSRF Tokens, but custom DRF tokens instead (that is what rest_framework.authtoken is for). Django Rest Framework视图中,您无需使用CSRF令牌,而可以使用自定义DRF令牌(即rest_framework.authtoken的用途)。 When you create a new user, you have to create his token, like this: 创建新用户时,必须创建其令牌,如下所示:

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)

Then, you have to get the token for the user, and send it in the header with key name Authorization and value Token <token> . 然后,您必须为用户获取令牌,并将其发送到键名称为Authorization且值为Token <token>的标头中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Django:“详细信息”:“未提供身份验证凭据。” - Django : “detail”: “Authentication credentials were not provided.” Django Rest 框架 - 未提供身份验证凭据 - Django Rest Framework - Authentication credentials were not provided Django OAuth Toolkit为我提供了“未提供身份验证凭据”错误 - Django OAuth Toolkit giving me “Authentication credentials were not provided” error Django OAuth 工具包 - 自省请求:“未提供身份验证凭据。” - Django OAuth Toolkit - Introspection Request: “Authentication credentials were not provided.” Django restframework,未提供身份验证凭据,knox-tokenauthentication - Django restframework, Authentication credentials were not provided, knox-tokenauthentication 详细信息:未提供身份验证凭据 - details:Authentication credentials were not provided 获取:未提供身份验证凭据 - Fetch : authentication credentials were not provided django rest 框架中未提供错误身份验证凭据 - getting error Authentication credentials were not provided in django rest framework Python 请求与 Django Rest 框架 - “详细信息”:“未提供身份验证凭据” - Python Requests with Django Rest Framework - 'detail': 'Authentication credentials were not provided' Django Rest Framework JWT“未提供身份验证凭据。”} - Django Rest Framework JWT “Authentication credentials were not provided.”}
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM