Django Rest Framework 请求对 AllowAny 设置进行身份验证 [英] Django Rest Framework requesting authentication on AllowAny setting
问题描述
我创建了一个 JWT-Authorised 后端应用程序.登录、注销、令牌检索和刷新都可以正常工作,并且符合预期.今天早上我添加了一个注册视图,它抛出了通常的 "detail": "Authentication credentials were not provided.
错误你会期望未验证的请求,因为这是默认的(见下文).
I've created a JWT-Authorised back end for an app. Login, logout, token retrieval and refresh all work fine, and as expected. I added a registration view this morning, which is throwing the usual "detail": "Authentication credentials were not provided.
error you'd expect for non-authenticated requests, as that's the default (see below).
但是,因为这是一个注册端点,我不希望它只允许授权请求.(使用有效令牌进行检查后,当您提供身份验证时,视图的其余部分按预期工作.)查看 DRF docs,我认为将 permission_classes 包装器与 AllowAny 一起使用在这里可以工作,但事实并非如此.
However, because this is a registration endpoint, I don't want it to only allow authorised requests. (Having checked with a valid token, the rest of the view works as expected when you supply authentication.) Looking at the permissions section of the DRF docs, I thought that using the permission_classes wrapper with AllowAny would work here, but it hasn't.
我错过了什么?我觉得 permission_classes 装饰器应该覆盖IsAuthenticated"的默认设置?
What am I missing? I feel like the permission_classes decorator should override the default setting of 'IsAuthenticated'?
我正在通过 curl 在 localhost 上进行测试:
I'm testing on localhost from curl:
curl -X POST -H "Content-Type: application/json" -d '{"email":"boba@athingy09876.com", "first_name": "boba", "last_name": "fett" "password":"xyz"}' http://localhost:8000/account/register/
视图是:
@permission_classes(AllowAny)
@api_view(['POST'])
def register_user(request):
from django.contrib.auth.models import User
from rest_framework_jwt.views import obtain_jwt_token
if request.user.is_authenticated():
return Response ({"already_registered": "User with that username has already registered"}, status=status.HTTP_701_ALREADY_REGISTERED)
data = request.data
user, created = User.objects.get_or_create(username=data["email"],
email=data["email"],
first_name=data["first_name"],
last_name=data["last_name"],
password=data["password"])
if created:
token = obtain_jwt_token(data["email"],data["password"] )
return Response ({"token": token}, status=status.HTTP_200_OK)
else:
return Response ({"already_registered": "User with that username has already registered"}, status=status.HTTP_701_ALREADY_REGISTERED)
settings.py 中的权限是:
Permissions in settings.py are:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
),
}
相关问题:Django Rest Framework - 未提供身份验证凭据 - 我认为默认权限是正确的,我只想在这种情况下覆盖它们.
Related questions: Django Rest Framework - Authentication credentials were not provided - I think the default permissions are correct, I just want to override them in this instance.
Django Rest 框架 - 删除由于错误的 CSFR 令牌导致 ajax 调用失败 - CSRF 未被用作基于 JWT 的身份验证.
Django Rest Framework - DELETE ajax call failure due to incorrect CSFR token - CSRF not being used as JWT Based auth.
Django:Rest Framework 验证标头 - Apache 特定问题(目前仍在开发服务器上本地主机)
Django: Rest Framework authenticate header - Apache specific issue (currently still on devserver localhost)
未提供 Django Rest 框架身份验证凭据 -还没有回答!
推荐答案
装饰器的顺序很重要.您的代码也存在一些问题.
The order of the decorators matter. There's also some problems with your code.
我建议使用序列化程序,可能如下所示.如果您想使用电子邮件作为用户名,我会制作一个自定义用户模型.Django 的默认身份验证系统的用户名字段的 max_length 为 30,人们的电子邮件地址很容易超过.
I recommend using a serializer, maybe something like below. If you want to use emails as username, I would make a custom User model. Django's default authentication system's username field has max_length of 30, and people's email addresses easily surpass that.
class UserSerializer(serializers.ModelSerializer):
first_name = serializers.CharField(required=False, allow_null=True)
last_name = serializers.CharField(required=False, allow_null=True)
class Meta:
model = User
fields = ('id', 'username', 'first_name', 'last_name', 'email', 'password')
def create(self, validated_data):
return User.objects.create_user(**validated_data)
@api_view(['POST'])
@permission_classes([permissions.AllowAny,])
def register_user(request):
if request.user.is_authenticated():
return Response({"already_registered": "User with that username has already registered"}, status=701)
data = request.data
serializer = UserSerializer(data=data, partial=True)
if serializer.is_valid():
serializer.save(username=serializer.validated_data['email'])
token = #call the url to get your tokens, use urllib or something similar
return Response({"token": token}, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
编辑装饰器的顺序是这样的:
Edit The ordering of decorators goes like this:
@decorator
@decorator2
def func():
print('hello world')
同装饰器(decorator2(func)))
Is the same as decorator(decorator2(func)))
这篇关于Django Rest Framework 请求对 AllowAny 设置进行身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!