为了避免垃圾邮件,我想添加一个等待时间来重新提交表单(即用户应该等待几秒钟提交表单,除了第一次提交此表单< /强>)。
为此,我在表单中添加了一个timestamp
(以及一个包含时间戳加security_hash
的{{1}}字段,以确保时间戳不会被填充。这看起来像:
settings.SECRET_KEY
这很好用。但是仍然存在一个问题:用户首次提交表单时会检查时间戳,我需要避免使用。
有什么想法来解决它吗?
谢谢! : - )
答案 0 :(得分:2)
用户第一次提交表单时会检查时间戳,我需要避免这种情况。
如果这是问题,您是否无法创建设置时间戳-5分钟的表单?
答案 1 :(得分:2)
执行此操作的一种方法是将initial值设置为time,假设为0,并在表单验证后将其更新为当前时间戳,并仅在不为0时检查时间戳:
class MyForm(forms.Form):
timestamp = forms.IntegerField(widget=forms.HiddenInput, initial=0)
#look at the initial = 0
security_hash = forms.CharField(min_length=40, max_length=40, widget=forms.HiddenInput)
def clean_timestamp(self):
"""Make sure the delay is over (5 seconds)."""
ts = self.cleaned_data["timestamp"]
if timestamp != 0 and not time.time() - ts > 5:
raise forms.ValidationError("Timestamp check failed")
return ts
def clean(self):
cleaned_data = self.cleaned_data
if len(self._errors) == 0: #it validates
cleaned_data["timestamp"] = time.time()
return cleaned_data
另一种可能的解决方案是使用sessions。它更安全但不防弹。使用之前的apporach,用户可以多次发送相同的发布数据,并且表单将多次验证(因为他发送的是相同的时间戳)。使用会话时,您需要用户启用Cookie,但他们将无法发送验证时间超过5秒的帖子数据。
这样一旦正确的表单提交发生,您可以将时间保存在用户的会话密钥中,并在重新验证表单之前进行检查。这在视图中很容易完成。如果要在表单逻辑级别执行此操作,则需要在接收请求的表单中创建自己的clean方法(以便可以使用会话)。请注意,用户可以清理他的cookie并以“新”用户身份发布。
希望这有帮助。