Django Rest Framework 请求对 AllowAny 设置进行身份验证

Wit*_*ail 5 authentication python-2.7 jwt django-rest-framework django-1.6

我为应用程序创建了JWT 授权的后端。登录、注销、令牌检索和刷新都按预期工作正常。我今天早上添加了一个注册视图,它抛出了"detail": "Authentication credentials were not provided.您对未经身份验证的请求所期望的常见错误,因为这是默认设置(见下文)。

但是,因为这是一个注册端点,我不希望它只允许授权请求。(使用有效令牌进行检查后,视图的其余部分在您提供身份验证时按预期工作。)查看DRF 文档的权限部分,我认为将 permission_classes 包装器与 AllowAny 一起使用可以在这里工作,但它没有.

我错过了什么?我觉得permission_classes 装饰器应该覆盖'IsAuthenticated' 的默认设置吗?

我正在从 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/
Run Code Online (Sandbox Code Playgroud)

视图是:

@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)
Run Code Online (Sandbox Code Playgroud)

settings.py 中的权限是:

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',
    ),
}
Run Code Online (Sandbox Code Playgroud)

相关问题: Django Rest Framework - 未提供身份验证凭据- 我认为默认权限是正确的,我只想在这种情况下覆盖它们。

Django Rest Framework - 由于不正确的 CSFR 令牌而删除 ajax 调用失败- CSRF 未被用作基于 JWT 的身份验证。

Django:Rest Framework 身份验证标头- Apache 特定问题(目前仍在开发服务器本地主机上)

未提供 Django Rest Framework 身份验证凭据- 尚未回答!

Jaa*_*kko 5

装饰器的顺序很重要。你的代码也有一些问题。

我建议使用序列化程序,可能如下所示。如果你想使用电子邮件作为用户名,我会制作一个自定义的用户模型。Django 的默认身份验证系统的用户名字段的 max_length 为 30,人们的电子邮件地址很容易超过它。

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)
Run Code Online (Sandbox Code Playgroud)

编辑 装饰器的顺序是这样的:

@decorator
@decorator2
def func():
    print('hello world')
Run Code Online (Sandbox Code Playgroud)

与decorator(decorator2(func)))相同


Kev*_*own 4

您已使用 禁用了权限@permission_classes,但这只是“身份验证和授权”的“授权”部分。您还需要禁用身份验证处理程序@authentication_classes以停止接收 401/403 错误。