首页 文章

Django Rest Framework在AllowAny设置上请求身份验证

提问于
浏览
3

我为应用创建了一个JWT-Authorised后端 . 登录,注销,令牌检索和刷新所有工作正常,并按预期 . 我今天早上添加了一个注册视图,它抛出了常见的 "detail": "Authentication credentials were not provided. 错误,你是默认的(见下文) .

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

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

我正在curl上测试localhost:

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中的权限是:

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 - Authentication credentials were not provided - 我认为默认权限是正确的,我只想在这个实例中覆盖它们 .

Django Rest Framework - DELETE ajax call failure due to incorrect CSFR token - CSRF未被用作基于JWT的身份验证 .

Django: Rest Framework authenticate header - Apache特定问题(目前仍在devserver localhost上)

Django Rest Framework Authentication credentials were not provided - 尚未回答!

2 回答

  • 4

    装饰者的顺序很重要 . 您的代码也存在一些问题 .

    我建议使用序列化器,可能如下所示 . 如果您想使用电子邮件作为用户名,我会创建一个自定义用户模型 . 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)
    

    Edit 装饰器的顺序如下:

    @decorator
    @decorator2
    def func():
        print('hello world')
    

    与装饰器相同(decorator2(func)))

  • 2

    您已使用 @permission_classes 禁用了权限,但这只是"authentication and authorization"的"authorization"部分 . 您还需要使用 @authentication_classes 禁用the authentication handlers以便停止接收401/403错误 .

相关问题