gpt4 book ai didi

python - 将 Autocomplete=off 应用到 Django 密码重置确认表单

转载 作者:太空宇宙 更新时间:2023-11-03 20:36:14 25 4
gpt4 key购买 nike

我正在使用 Django 2.2 和 Python 3.7

经过安全审核后,我被要求确保应用程序中表单上所有与安全相关的字段都使用 autocomplete="off"属性呈现。不幸的是,这是否是有效且有用的安全措施超出了范围。到目前为止,我已经通过扩展相关表格来完成此任务。例如,使用PasswordResetForm(用户输入与帐户关联的电子邮件):

class NoAutocompletePasswordResetForm(PasswordResetForm):
def __init__(self, *args, **kwargs):
super(PasswordResetForm, self).__init__(*args, **kwargs)
self.fields['email'].widget.attrs.update({'autocomplete': 'off'})

然后指示相关的身份验证 View 像这样使用它(在 urls.py 中):

    url(r'^accounts/password_reset/?$', auth_views.PasswordResetView.as_view(form_class=forms.NoAutocompletePasswordResetForm)),

在使用 SetPasswordForm 的密码重置确认 View 之前,这一切都运行良好。第一次尝试是这样的:

url(r'^accounts/reset/(?P<uidb64>[0-9A-Za-z]+)/(?P<token>[0-9A-Za-z\-]+)/$', auth_views.PasswordResetConfirmView.as_view(form_class=forms.NoAutocompleteSetPasswordForm)),

class NoAutocompleteSetPasswordForm(SetPasswordForm):
def __init__(self, *args, **kwargs):
super(SetPasswordForm, self).__init__(*args, **kwargs)
self.fields['new_password1'].widget.attrs.update({'autocomplete': 'off'})
self.fields['new_password2'].widget.attrs.update({'autocomplete': 'off'})

然而,这只会在 super() 行上产生 TypeError,其详细信息是 __init__() 获得意外的关键字参数“user”,尽管存在命名的 user 参数传递给该形式的 init,如 in the Django source 所示。 。但为了好玩,我尝试将用户作为位置参数传递,如下所示:

class NoAutocompleteSetPasswordForm(SetPasswordForm):
def __init__(self, *args, **kwargs):
myKwargs = kwargs.copy()
myUser = myKwargs['user']
del myKwargs['user']

myArgs = (*args, myUser)

super(SetPasswordForm, self).__init__(*myArgs, **myKwargs)
self.fields['new_password1'].widget.attrs.update({'autocomplete': 'off'})
self.fields['new_password2'].widget.attrs.update({'autocomplete': 'off'})

通过这个调整,表单可以通过构建,但是 Django 在模板渲染过程中出错了。特别是,我得到以下堆栈跟踪:

Internal Server Error: /accounts/reset/MjA/set-password/
Traceback (most recent call last):
File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\base.py", line 829, in _resolve_lookup
current = current[bit]
File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\forms\boundfield.py", line 66, in __getitem__
raise TypeError
TypeError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\core\handlers\base.py", line 145, in _get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\core\handlers\base.py", line 143, in _get_response
response = response.render()
File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\response.py", line 106, in render
self.content = self.rendered_content
File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\response.py", line 83, in rendered_content
content = template.render(context, self._request)
File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\backends\django.py", line 61, in render
return self.template.render(context)
File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\base.py", line 171, in render
return self._render(context)
File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\base.py", line 163, in _render
return self.nodelist.render(context)
File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\base.py", line 937, in render
bit = node.render_annotated(context)
File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\base.py", line 904, in render_annotated
return self.render(context)
File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\defaulttags.py", line 309, in render
return nodelist.render(context)
File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\base.py", line 937, in render
bit = node.render_annotated(context)
File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\base.py", line 904, in render_annotated
return self.render(context)
File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\base.py", line 987, in render
output = self.filter_expression.resolve(context)
File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\base.py", line 671, in resolve
obj = self.var.resolve(context)
File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\base.py", line 796, in resolve
value = self._resolve_lookup(context)
File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\template\base.py", line 837, in _resolve_lookup
current = getattr(current, bit)
File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\forms\boundfield.py", line 74, in errors
return self.form.errors.get(self.name, self.form.error_class())
File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\forms\forms.py", line 180, in errors
self.full_clean()
File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\forms\forms.py", line 381, in full_clean
self._clean_fields()
File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\forms\forms.py", line 393, in _clean_fields
value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
File "C:\Users\Ben\Documents\Delorean\delorean_env_37\lib\site-packages\django\forms\widgets.py", line 258, in value_from_datadict
return data.get(name)
AttributeError: 'User' object has no attribute 'get'

那么,如何让此表单以 autocomplete='off' 呈现?

最佳答案

经过一番拉扯,我终于成功了。从 here 汲取灵感,并且基于我曾经收到有关意外用户参数的错误这一事实,我将表单更改为以下内容:

class NoAutocompleteSetPasswordForm(SetPasswordForm):
def __init__(self, user, *args, **kwargs):
self.user = user

super(SetPasswordForm, self).__init__(*args, **kwargs)
self.fields['new_password1'].widget.attrs.update({'autocomplete': 'off'})
self.fields['new_password2'].widget.attrs.update({'autocomplete': 'off'})

它现在根据需要呈现具有自动完成属性的页面。

关于python - 将 Autocomplete=off 应用到 Django 密码重置确认表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57152846/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com