Django:如何应用内置的密码验证器?
Django: How to apply the built-in password validators?
我喜欢在注册表单上测试 django 内置验证器。所以我添加了这个...
settings.py
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
'OPTIONS': {
'min_length': 9,
}
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
forms.py
from django.contrib.auth.models import User
from django import forms
import django.contrib.auth.password_validation as validators
class UserRegistrationForm(forms.ModelForm):
password = forms.CharField(label='Password',
widget=forms.PasswordInput)
password2 = forms.CharField(label='Repeat password',
widget=forms.PasswordInput)
class Meta:
model = User
fields = ('username', 'first_name', 'email')
# --- check duplicate
def clean_password2(self):
cd = self.cleaned_data
if cd['password'] != cd['password2']:
raise forms.ValidationError('Passwords don\'t match.')
return cd['password2']
# --- django built-in validator
def pass_validate(self):
password = self.cleaned_data('password')
try:
validators(password, self.instance)
except forms.ValidationError as error:
self.add_error('password', error)
return password
views.py
<...>
def register(request):
if request.method == 'POST':
user_form = UserRegistrationForm(request.POST)
if user_form.is_valid():
# Create a new user object but avoid saving it yet
new_user = user_form.save(commit=False)
# Set the chosen password
new_user.set_password(
user_form.cleaned_data['password'])
# Save the User object
new_user.save()
return render(request,
'account/register_done.html',
{'new_user': new_user})
else:
user_form = UserRegistrationForm()
return render(request,
'account/register.html',
{'user_form': user_form})
<...>
- 不幸的是,我仍然可以使用“123”之类的密码注册为用户。所以min_length是行不通的。
- forms.py 中的
pass_validate
函数是一种添加 django 内置验证器的方法,在阅读了论坛中的一些文章后。
- 好消息是服务器正常运行并且没有显示任何错误。
所以我的问题是 “如何以正确的方式应用内置密码验证器”?我需要一个特殊的 validators.py 吗?但我猜我把 forms.py 中的函数弄错了。
您可以实施 UserCreationForm
以便您的 AUTH_PASSWORD_VALIDATORS
可以正常工作。
例如:
forms.py
from django.contrib.auth.forms import UserCreationForm
class RegisterForm(UserCreationForm):
def clean_email(self):
email = self.cleaned_data['email']
if User.objects.filter(email=email).exists():
raise ValidationError('Email Already Exists')
return email
class Meta:
model = User
fields = ['username', "email", "password1", "password2"]
views.py
def register(request):
if request.method == "POST":
form = RegisterForm(request.POST or None)
if form.is_valid():
form.save()
return redirect('some_view')
else:
form = RegisterForm()
return render(request, 'template', {'form': form})
与其他模型验证一样,需要显式调用密码验证。您可以通过直接调用 validate_password
来触发密码验证。
from django.contrib.auth.models import User
from django import forms
from django.contrib.auth.password_validation import validate_password
class UserRegistrationForm(forms.ModelForm):
password = forms.CharField(label='Password',
widget=forms.PasswordInput)
password2 = forms.CharField(label='Repeat password',
widget=forms.PasswordInput)
class Meta:
model = User
fields = ('username', 'first_name', 'email')
# --- django built-in validator
def clean_password(self):
password = self.cleaned_data['password']
validate_password(password)
return password
# --- check duplicate
def clean_password2(self):
cd = self.cleaned_data
if cd['password'] != cd['password2']:
raise forms.ValidationError('Passwords don\'t match.')
return cd['password2']
如果您不想使用所有默认值,您可以通过 validate_password
个单独的验证器。参见 help(validate_password)
。
我喜欢在注册表单上测试 django 内置验证器。所以我添加了这个...
settings.py
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
'OPTIONS': {
'min_length': 9,
}
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
forms.py
from django.contrib.auth.models import User
from django import forms
import django.contrib.auth.password_validation as validators
class UserRegistrationForm(forms.ModelForm):
password = forms.CharField(label='Password',
widget=forms.PasswordInput)
password2 = forms.CharField(label='Repeat password',
widget=forms.PasswordInput)
class Meta:
model = User
fields = ('username', 'first_name', 'email')
# --- check duplicate
def clean_password2(self):
cd = self.cleaned_data
if cd['password'] != cd['password2']:
raise forms.ValidationError('Passwords don\'t match.')
return cd['password2']
# --- django built-in validator
def pass_validate(self):
password = self.cleaned_data('password')
try:
validators(password, self.instance)
except forms.ValidationError as error:
self.add_error('password', error)
return password
views.py
<...>
def register(request):
if request.method == 'POST':
user_form = UserRegistrationForm(request.POST)
if user_form.is_valid():
# Create a new user object but avoid saving it yet
new_user = user_form.save(commit=False)
# Set the chosen password
new_user.set_password(
user_form.cleaned_data['password'])
# Save the User object
new_user.save()
return render(request,
'account/register_done.html',
{'new_user': new_user})
else:
user_form = UserRegistrationForm()
return render(request,
'account/register.html',
{'user_form': user_form})
<...>
- 不幸的是,我仍然可以使用“123”之类的密码注册为用户。所以min_length是行不通的。
- forms.py 中的
pass_validate
函数是一种添加 django 内置验证器的方法,在阅读了论坛中的一些文章后。 - 好消息是服务器正常运行并且没有显示任何错误。
所以我的问题是 “如何以正确的方式应用内置密码验证器”?我需要一个特殊的 validators.py 吗?但我猜我把 forms.py 中的函数弄错了。
您可以实施 UserCreationForm
以便您的 AUTH_PASSWORD_VALIDATORS
可以正常工作。
例如:
forms.py
from django.contrib.auth.forms import UserCreationForm
class RegisterForm(UserCreationForm):
def clean_email(self):
email = self.cleaned_data['email']
if User.objects.filter(email=email).exists():
raise ValidationError('Email Already Exists')
return email
class Meta:
model = User
fields = ['username', "email", "password1", "password2"]
views.py
def register(request):
if request.method == "POST":
form = RegisterForm(request.POST or None)
if form.is_valid():
form.save()
return redirect('some_view')
else:
form = RegisterForm()
return render(request, 'template', {'form': form})
与其他模型验证一样,需要显式调用密码验证。您可以通过直接调用 validate_password
来触发密码验证。
from django.contrib.auth.models import User
from django import forms
from django.contrib.auth.password_validation import validate_password
class UserRegistrationForm(forms.ModelForm):
password = forms.CharField(label='Password',
widget=forms.PasswordInput)
password2 = forms.CharField(label='Repeat password',
widget=forms.PasswordInput)
class Meta:
model = User
fields = ('username', 'first_name', 'email')
# --- django built-in validator
def clean_password(self):
password = self.cleaned_data['password']
validate_password(password)
return password
# --- check duplicate
def clean_password2(self):
cd = self.cleaned_data
if cd['password'] != cd['password2']:
raise forms.ValidationError('Passwords don\'t match.')
return cd['password2']
如果您不想使用所有默认值,您可以通过 validate_password
个单独的验证器。参见 help(validate_password)
。