Django Rest框架在AllowAny设置上请求身份验证 [英] Django Rest Framework requesting authentication on AllowAny setting

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

问题描述

我已经创建了一个 JWT授权的后端应用程序。登录,注销,令牌检索和刷新所有工作正常,并按预期。我今天早上添加了一个注册视图,这是抛出通常的detail:没有提供身份验证凭证。错误,你会期望未经身份验证的请求,因为默认值(见下文)。



但是,由于这是一个注册端点,我不希望它只允许授权的请求(使用有效的令牌检查,其余的视图在提供身份验证时按预期方式工作。)查看 DRF docs ,我以为用AllowAny的permission_classes包装器可以在这里工作,但是没有。



?我觉得permission_classes的装饰器应该覆盖'IsAuthenticated'的默认设置?



我正在curl测试本地主机:

  curl -X POST -HContent-Type:application / json-d'{ email:boba@athingy09876.com,first_name:boba,last_name:fettpassword:xyz}'http:// localhost:8000 / account / register / 

查看是:

  @permission_classes(AllowAny)
@api_view(['POST'])
def register_user(request):
from django.contrib.auth.models import User
来自rest_framework_jwt.views import get_jwt_token
如果request.user.is_authenticated():
返回响应({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])
如果创建:
token = gets_jwt_token(data [email],data [password])
return响应({token令牌},status = status.HTTP_200_OK)
else:
返回响应({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框架 - 没有提供身份验证凭据 - 我认为默认的权限是正确的,我只想在这个例子中覆盖它们。 / p>

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



Django:Rest框架验证头 - Apache特定问题(目前仍在devserver localhost上)



Django Rest框架认证凭证未提供 - 尚未回覆!

解决方案

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



我建议使用一个序列化程序,也许像下面这样。如果您要使用电子邮件作为用户名,我将自定义用户模型。 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 =
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.user.is_authenticated():
返回响应({already_registered:该用户名的用户已经注册},status = 701)
data = request.data
serializer = UserSerializer(data = data,partial =真的)
如果serializer.is_valid():
serializer.save(username = serializer.validated_data ['email'])
token = #call url来获取你的令牌,使用urllib或类似的
返回响应({token:token},status = status.HTTP_201_CREATED)
else:
返回响应(serializer.errors,status = status.HTTP_400_BAD_REQUEST)

修改
装饰器的顺序如下所示:

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

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


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

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.

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/

View is:

@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)

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

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 Framework - DELETE ajax call failure due to incorrect CSFR token - CSRF not being used as JWT Based auth.

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

Django Rest Framework Authentication credentials were not provided - Not yet answered!

解决方案

The order of the decorators matter. There's also some problems with your code.

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

Is the same as decorator(decorator2(func)))

这篇关于Django Rest框架在AllowAny设置上请求身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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