Gui*_*Gui 1 python authentication django
我正在为 Django 创建一个自定义身份验证应用程序,一切都很好,用户需要验证电子邮件以设置 is_active True,这就像一个魅力,但是一旦用户发送电子邮件并且令牌过期,用户就会尝试登录并收到用户或通过不正确的消息,我想显示用户必须激活帐户并提供链接以将激活令牌重新发送到他的电子邮件。
我正在使用默认的登录视图:
url(r'^login/$', auth_views.LoginView.as_view(template_name='accounts/login.html'), name='account_login')
Run Code Online (Sandbox Code Playgroud)
如何修改此视图或其他内容以显示用户未处于活动状态?
查看来自 Django auth 的 AuthenticationForm 我可以看到有一个非活动用户错误,但在登录表单中只引发了错误 invalid_login 。
class AuthenticationForm(forms.Form):
"""
Base class for authenticating users. Extend this to get a form that accepts
username/password logins.
"""
username = UsernameField(
max_length=254,
widget=forms.TextInput(attrs={'autofocus': True}),
)
password = forms.CharField(
label=_("Password"),
strip=False,
widget=forms.PasswordInput,
)
error_messages = {
'invalid_login': _(
"Please enter a correct %(username)s and password. Note that both "
"fields may be case-sensitive."
),
'inactive': _("This account is inactive."),
}
def __init__(self, request=None, *args, **kwargs):
"""
The 'request' parameter is set for custom auth use by subclasses.
The form data comes in via the standard 'data' kwarg.
"""
self.request = request
self.user_cache = None
super(AuthenticationForm, self).__init__(*args, **kwargs)
# Set the label for the "username" field.
self.username_field = UserModel._meta.get_field(UserModel.USERNAME_FIELD)
if self.fields['username'].label is None:
self.fields['username'].label = capfirst(self.username_field.verbose_name)
def clean(self):
username = self.cleaned_data.get('username')
password = self.cleaned_data.get('password')
if username is not None and password:
self.user_cache = authenticate(self.request, username=username, password=password)
if self.user_cache is None:
raise forms.ValidationError(
self.error_messages['invalid_login'],
code='invalid_login',
params={'username': self.username_field.verbose_name},
)
else:
self.confirm_login_allowed(self.user_cache)
return self.cleaned_data
def confirm_login_allowed(self, user):
"""
Controls whether the given User may log in. This is a policy setting,
independent of end-user authentication. This default behavior is to
allow login by active users, and reject login by inactive users.
If the given user cannot log in, this method should raise a
``forms.ValidationError``.
If the given user may log in, this method should return None.
"""
if not user.is_active:
raise forms.ValidationError(
self.error_messages['inactive'],
code='inactive',
)
def get_user_id(self):
if self.user_cache:
return self.user_cache.id
return None
def get_user(self):
return self.user_cache
Run Code Online (Sandbox Code Playgroud)
我能够从 AuthenticationForm 类中更正这个覆盖干净的方法。
class LoginForm(AuthenticationForm):
def clean(self):
username = self.cleaned_data.get('username')
password = self.cleaned_data.get('password')
if username is not None and password:
self.user_cache = authenticate(self.request, username=username, password=password)
if self.user_cache is None:
try:
user_temp = User.objects.get(username=username)
except:
user_temp = None
if user_temp is not None:
self.confirm_login_allowed(user_temp)
else:
raise forms.ValidationError(
self.error_messages['invalid_login'],
code='invalid_login',
params={'username': self.username_field.verbose_name},
)
return self.cleaned_data
Run Code Online (Sandbox Code Playgroud)
非活动用户永远不会被提升,这是因为在 Django 1.10 之后,所有非活动用户都无法进行身份验证,因此对于非活动用户, self.user_chache 始终为 None ,即使有正确的用户并通过。
小智 5
这引入了 Django 2.0.2 中修复的信息泄露问题(另请参阅https://code.djangoproject.com/ticket/28645)。
此外,您应该检查用户是否提供了正确的密码:
def clean(self):
username = self.cleaned_data.get('username')
password = self.cleaned_data.get('password')
if username is not None and password:
self.user_cache = authenticate(self.request, username=username, password=password)
if self.user_cache is None:
try:
user_temp = User.objects.get(username=username)
except:
user_temp = None
if user_temp is not None and user_temp.check_password(password):
self.confirm_login_allowed(user_temp)
else:
raise forms.ValidationError(
self.error_messages['invalid_login'],
code='invalid_login',
params={'username': self.username_field.verbose_name},
)
return self.cleaned_data
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4751 次 |
| 最近记录: |