要在我的Django Web应用程序中注册用户,我创建了功能,该功能发送一个密码签名的链接到已验证的电子邮件地址,使他们可以访问用户注册页面。现在的下一步是确保链接在设置的时间后过期,但这比预期的要难。
通过这个,我一直在使用内置的Django Signer函数,现在的想法是将其转换为TimestampSigner函数。为此,我已阅读并遵循: https://docs.djangoproject.com/en/2.2/topics/signing/#verifying-timestamped-values
这是我的代码:
在models.py中:
class GenerateUserRegistration(models.Model):
signer = TimestampSigner(sep='/', salt='users.GenerateUserRegistration')
def get_registration_url(self, pk):
signed_pk = self.signer.sign(pk)
domain = Site.objects.get_current().domain
path = str(reverse('register', kwargs={'signed_pk': signed_pk}))
registration_url = 'http://{domain}{path}'.format(domain=domain, path=path)
return registration_url
在views.py中:
def register(request, signed_pk):
try:
pk = GenerateUserRegistration.signer.unsign(signed_pk, max_age=30)
confirmed = Program.objects.get(id=pk)
except (BadSignature, GenerateUserRegistration.DoesNotExist):
raise Http404(signed_pk)
def generate_user_registration_email(request):
...
UserGenerator = GenerateUserRegistration()
user_registration_url = UserGenerator.get_registration_url(pk)
send_mail('app specific data')
...
在urls.py中:
urlpatterns = [
...
re_path(r'register/(?P<signed_pk>[0-9]+/[A-Za-z0-9_=-]+)/$', user_views.register,name='register'),
...
当使用TimestampSigner而不是Signer运行程序时(它的工作原理与预期的一样),它引发以下错误:
“ NoReverseMatch位于/ admin / generate-user-registration 找不到带有关键字参数'{'signed_pk':'1 / 1hUBvf / 3EiPZDorfNCqovGyDjoO--9oyTQ'}的'register'。尝试了1个模式:['register /(?P [0-9] + / [A-Za-z0-9 _ =-] +)/ $']“
这使我相信我必须以某种方式修改URL以适应TimestampSigner,但是我在文档中找不到任何内容。在那里需要修改什么才能使其起作用?
谢谢!
答案 0 :(得分:0)
urlpatterns
中的正则表达式必须与带符号的字符串的格式匹配。如the documentation中所述,带有时间戳的带符号字符串的格式与常规带符号字符串的格式不同;具体来说,它“将签名时间戳附加到该值上。”
因此您需要更改url模式以使其匹配,即:
r'register/(?P<signed_pk>[0-9]+/[A-Za-z0-9_=-]+/[A-Za-z0-9_=-]+)/$'
但是,我建议您不要使用/
作为分隔符,因为该字符在URL中具有语义。使用$
之类的URL safe字符。