Django的休息框架要求对AllowAny设置身份验证 [英] Django Rest Framework requesting authentication on AllowAny setting

查看:1954
本文介绍了Django的休息框架要求对AllowAny设置身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个智威汤逊,授权后端为应用。登录,注销,令牌检索和刷新所有做工精细,并符合市场预期。今天早上我增加了一个注册视图,这是投掷通常的细节:不提供身份验证凭据错误你所期望的非认证的请求,因为这是默认值(见下文)。

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文档,我认为使用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'?

我在本地主机上的卷曲测试:

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

相关问题:
<一href=\"http://stackoverflow.com/questions/26906630/django-rest-framework-authentication-credentials-were-not-provided\">Django其余的框架 - 没有提供身份验证凭据 - 我觉得默认的权限是正确的,我只是想重写它们在这种情况下

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.

<一个href=\"http://stackoverflow.com/questions/27036881/django-rest-framework-delete-ajax-call-failure-due-to-incorrect-csfr-token\">Django休息框架 - 删除ajax调用失败由于不正确的CSFR令牌 - CSRF不被用作基于智威汤逊AUTH

Django Rest Framework - DELETE ajax call failure due to incorrect CSFR token - CSRF not being used as JWT Based auth.

的Django:休息框架身份验证标头 - 阿帕奇具体问题(目前仍在devserver本地主机)

Django: Rest Framework authenticate header - Apache specific issue (currently still on devserver localhost)

<一个href=\"http://stackoverflow.com/questions/29043310/django-rest-framework-authentication-credentials-were-not-provided\">Django休息框架身份验证凭据没有提供 - 尚未回答

推荐答案

在装饰的顺序关系。还有一些问题与code。

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的休息框架要求对AllowAny设置身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆