将django密码验证器与django rest框架validate_password集成 [英] integrate django password validators with django rest framework validate_password

查看:261
本文介绍了将django密码验证器与django rest框架validate_password集成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试集成 django验证器 1.9与django rest框架序列化程序。但是(Django REST框架的)序列化用户与Django验证程序不兼容。

I'm trying to integrate django validators 1.9 with django rest framework serializers. But the serialized 'user' (of django rest framework) is not compatible with the django validators.

这里是serializers.py

Here is the serializers.py

import django.contrib.auth.password_validation as validators
from rest_framework import serializers

    class RegisterUserSerializer(serializers.ModelSerializer):

        password = serializers.CharField(style={'input_type': 'password'}, write_only=True)

        class Meta:
            model = User
            fields = ('id', 'username', 'email, 'password')

        def validate_password(self, data):
            validators.validate_password(password=data, user=User)
            return data

        def create(self, validated_data):
            user = User.objects.create_user(**validated_data)
            user.is_active = False
            user.save()
            return user

我设法g MinimumLengthValidator和NumericPasswordValidator正确,因为两个函数均未在验证中使用用户。源代码是此处

I managed to get MinimumLengthValidator and NumericPasswordValidator correct because both function validate don't use 'user' in validating. Source code is here

摘录自Django源代码:

Excerpt from django source code:

def validate(self, password, user=None):
        if password.isdigit():
            raise ValidationError(
                _("This password is entirely numeric."),
                code='password_entirely_numeric',
            )

对于其他验证器(如UserAttributeSimilarityValidator),该函数在验证时使用另一个参数 user( user'是django用户模型,如果我没记错的话)

For other validators like UserAttributeSimilarityValidator, the function uses another one argument 'user' in validating ('user' is django User model, if I'm not wrong)

django源代码摘录:

Excerpt from django source code:

 def validate(self, password, user=None):
        if not user:
            return

        for attribute_name in self.user_attributes:
            value = getattr(user, attribute_name, None)

如何将序列化的用户更改为django验证器(UserAttributeSimilarityValidator)可以看到的内容

django源代码的摘录:

Excerpt from django source code:

def validate(self, password, user=None):
        if not user:
            return

        for attribute_name in self.user_attributes:
            value = getattr(user, attribute_name, None)
            if not value or not isinstance(value, string_types):
                continue






编辑

Django Rest Framework可以获取Django的所有内置密码验证(但就像黑客一样)。这是一个问题:

Django Rest Framework can get all of Django's built-in password validation (but it's like a hack). Here's a problem:

validationError就是这样

The validationError is like this


[ValidationError([ 此密码太短。它必须至少包含
个8个字符。']),ValidationError(['此密码完全是
个数字。'])]

[ValidationError(['This password is too short. It must contain at least 8 characters.']), ValidationError(['This password is entirely numeric.'])]

验证不包含字段。 Django rest框架将其视为

The validation doesn't contain a field. Django rest framework see it as

{
    "non_field_errors": [
        "This password is too short. It must contain at least 8 characters.",
        "This password is entirely numeric."
    ]
}

如何在<$ c $处注入字段c> raise ValidationError

推荐答案

就像您提到的那样,当您验证使用 UserAttributeSimilarityValidator 验证器的 validate_password 方法中的密码,您没有 user 对象。

Like you mentioned, when you validate the password in validate_password method using UserAttributeSimilarityValidator validator, you don't have the user object.

我建议您执行对象级验证,方法是实现 validate 方法:

What I suggest that instead of doing field-level validation, you shall perform object-level validation by implementing validate method on the serializer:

import sys
from django.core import exceptions
import django.contrib.auth.password_validation as validators

class RegisterUserSerializer(serializers.ModelSerializer):

     # rest of the code

     def validate(self, data):
         # here data has all the fields which have validated values
         # so we can create a User instance out of it
         user = User(**data)

         # get the password from the data
         password = data.get('password')

         errors = dict() 
         try:
             # validate the password and catch the exception
             validators.validate_password(password=password, user=User)

         # the exception raised here is different than serializers.ValidationError
         except exceptions.ValidationError as e:
             errors['password'] = list(e.messages)

         if errors:
             raise serializers.ValidationError(errors)

         return super(RegisterUserSerializer, self).validate(data)

这篇关于将django密码验证器与django rest框架validate_password集成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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