我希望Django Allauth使用https
发送确认电子邮件或重设密码等链接:
这样的事情:
https://example.com/ca/accounts/confirm-email/picuwfpjpptjswi50x5zb4gtsqptmwkscea445kadnbsfwcyij3fdnblery4onuq/
根据the official documentation仅更改settings.py
中的以下设置,它应该有效:
ACCOUNT_DEFAULT_HTTP_PROTOCOL = "https"
但是我继续使用http
而不是https
获取链接:
http://example.com/ca/accounts/confirm-email/picuwfpjpptjswi50x5zb4gtsqptmwkscea445kadnbsfwcyij3fdnblery4onuq/
我错过了什么吗?谢谢!
答案 0 :(得分:5)
稍微深入研究一下代码,您可以看到allauth
使用Django的activate_url
方法构建build_absolute_uri
模板上下文变量:
https://github.com/pennersr/django-allauth/blob/master/allauth/account/models.py#L119
...
activate_url = reverse("account_confirm_email", args=[self.key])
activate_url = request.build_absolute_uri(activate_url)
ctx = {
"activate_url": activate_url,
...
}
查看build_absolute_uri
的代码,您可以看到它需要一个环境变量:
https://github.com/django/django/blob/master/django/http/request.py#L153
def _get_scheme(self):
return 'https' if os.environ.get("HTTPS") == "on" else 'http'
要在此函数生成的网址中返回https://
,您需要设置HTTPS
环境变量。
这取决于您设置项目的方式,但您可以settings.py
或manage.py
以下是关于SSL的一般Django安全性的好帖子:
修改强>
奇怪的是,重置密码模板使用不同的方法来构建URL:
{{3}}
url = '%s://%s%s' % (app_settings.DEFAULT_HTTP_PROTOCOL,
current_site.domain,
path)
context = {"site": current_site,
"user": user,
"password_reset_url": url}
使用DEFAULT_HTTP_PROTOCOL
设置
答案 1 :(得分:1)
除了设置“ HTTPS”环境变量和SECURE_PROXY_SSL_HEADER SECURE_SSL_REDIRECT,当在适配器中使用.txt正文时,渲染模板并使用EmailMultiAlternatives()发送邮件时也可能出现问题。pyrender_mail() [1]:https://github.com/pennersr/django-allauth/blob/master/allauth/account/adapter.py
for ext in ["html", "txt"]:
try:
template_name = "{0}_message.{1}".format(template_prefix, ext)
bodies[ext] = render_to_string(
template_name,
context,
self.request,
).strip()
except TemplateDoesNotExist:
if ext == "txt" and not bodies:
# We need at least one body
raise
if "txt" in bodies:
msg = EmailMultiAlternatives(subject, bodies["txt"], from_email, to)
if "html" in bodies:
msg.attach_alternative(bodies["html"], "text/html")
else:
msg = EmailMessage(subject, bodies["html"], from_email, to)
msg.content_subtype = "html" # Main content is now text/html
return msg
例如print(body [ext])给出:
"To confirm this is correct, go to " https://127.0.0.1:8000/accounts/confirm-email/MjI:1kS0Mj:M5YfUf9-1Vg_TlgjVrK6vAtaLDE/ "
但是在电子邮件上仍然是http://
http://url7514.sitename/ls/click?upn=HJL2SSWV...
在大多数设备上也可以使用,因为应该仍然将其重定向到https://,但在某些设备上则不能,因此必须将默认模板/account/email/email_confirmation_message.txt更改为html扩展名, 结果之后:
To confirm this is correct, go to https://sitename/accounts/confirm-email/M...
答案 2 :(得分:0)
如果您在代理后面使用 django,则必须向 django 发送 https 标头。 在 apache2 中对我有用的是把它放在 apache2 上
<VirtualHost *:443>
RequestHeader set X-Forwarded-Proto 'https' env=HTTPS
添加标题后:
a2enmod headers
这在 django setting.py 上:
USE_X_FORWARDED_HOST = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
有了这个,我所有的 build_absolute_uri 都以 https 开头,模板也是如此,这包括密码恢复和身份验证邮件。