当前位置: 首页 > 知识库问答 >
问题:

将django密码验证器与django rest框架集成validate_password

孙翰墨
2023-03-14

我试图集成django验证器1.9与django rest框架序列化器。但是序列化的用户(django rest框架)与django验证器不兼容。

下面是序列化程序。派克

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

我设法使MinimumLengthValidator和NumericPasswordValidator正确,因为这两个函数validate在验证时都不使用“user”。源代码在这里

摘自django源代码:

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

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

摘自django源代码:

 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源代码:

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内置的密码验证(但这就像黑客攻击)。这里有一个问题:

验证错误是这样的

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

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

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

如何在raisevalidationerror

共有3个答案

梁烨
2023-03-14

使用序列化程序!使用validate\u fieldname方法!

class UserSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = (
            'id', 'username', 'password', 'first_name', 'last_name', 'email'
        )
        extra_kwargs = {
            'password': {'write_only': True},
            'username': {'read_only': True}
        }

    def validate_password(self, value):
        try:
            validate_password(value)
        except ValidationError as exc:
            raise serializers.ValidationError(str(exc))
        return value

    def create(self, validated_data):
        user = super().create(validated_data)
        user.set_password(validated_data['password'])

        user.is_active = False
        user.save()
        return user

    def update(self, instance, validated_data):
        user = super().update(instance, validated_data)
        if 'password' in validated_data:
            user.set_password(validated_data['password'])
            user.save()
        return user
宰父浩漫
2023-03-14

您可以通过self访问用户对象。实例,即使在执行字段级验证时也是如此。像这样的方法应该会奏效:

 from django.contrib.auth import password_validation

 def validate_password(self, value):
    password_validation.validate_password(value, self.instance)
    return value
楮阳
2023-03-14

就像您提到的,当您使用用户属性相似验证器验证validate_password方法中的密码时,您没有用户对象。

我的建议是,您应该通过在序列化器上实现valester方法来执行对象级验证,而不是执行字段级验证:

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)
 类似资料:
  • 我想知道是否有将自动化测试用例与zephy de jira集成的选项。 目前,我在robot框架中有一组自动测试。同时,我在Zephyr中为jira定义了测试用例。我希望能够从Zephyr启动自动测试用例的执行,否则执行的结果将反映在Zephyr测试用例中。 谢谢你。

  • 本文向大家介绍Django框架登录加上验证码校验实现验证功能示例,包括了Django框架登录加上验证码校验实现验证功能示例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Django框架登录加上验证码校验实现验证功能。分享给大家供大家参考,具体如下: 验证码生成函数 login.html html文件加上<img src="/verify_code" alt="">…当然这里还需要配置ur

  • 问题内容: 我正在使用最新的稳定Spring版本()。 将Hibernate从5.1升级到5.2,并将依赖项更改为适当的hibernate文档后:https : //github.com/hibernate/hibernate- orm/wiki/Migration-Guide—5.2 我没有收到任何编译错误,但是我的所有测试都因以下堆栈跟踪而失败: 问题答案: 中增加了支持,其稳定版本将于下周推

  • 问题内容: 我有一个角度应用程序,其中包含一个从示例中获取的保存按钮: 这对于客户端验证非常有用,因为当用户解决问题时它会变为false,但是我有一个电子邮件字段,如果另一个用户使用相同的电子邮件注册,则该字段设置为无效。 一旦我将电子邮件字段设置为无效,就无法提交表单,并且用户无法修复该验证错误。所以现在我不能再使用来禁用我的提交按钮。 肯定有更好的办法 问题答案: 我在几个项目中都需要这样做,

  • 本文向大家介绍SpringBoot集成kaptcha验证码,包括了SpringBoot集成kaptcha验证码的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了SpringBoot集成kaptcha验证码的具体代码,供大家参考,具体内容如下 1.kaptcha相关介绍 Kaptcha是一个基于SimpleCaptcha的验证码开源项目。 2.集成方案 ①pom.xml中配置依赖 ②配置

  • 本文向大家介绍python django集成cas验证系统,包括了python django集成cas验证系统的使用技巧和注意事项,需要的朋友参考一下 加入cas的好处 cas是什么东西就不多说了,简而言之就是单点登陆系统,一处登陆,全网有权限的系统均可以访问. 一次登陆,多个系统互通 cas一般均放置在内网,加入cas验证则必须要求用户走vpn访问,提高安全性; cas可和域控等系统结合,密码定