18👍
Digging into the code a little bit, you can see that allauth
sets the activate_url
template context variable using Django’s build in build_absolute_uri
method:
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,
...
}
Looking at the code for the build_absolute_uri
you can see it requires a environment variable:
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'
to return https://
in URLs generated by this function, you need to set a HTTPS
environment variable.
It depends on how you have set up your project, but you can set the environment variable in your settings.py
or manage.py
The following is a good post on general Django security when it comes to SSL:
EDIT
Strangely, the reset password template uses a different approach to constructing the URL:
https://github.com/pennersr/django-allauth/blob/master/allauth/account/forms.py#L428
url = '%s://%s%s' % (app_settings.DEFAULT_HTTP_PROTOCOL,
current_site.domain,
path)
context = {"site": current_site,
"user": user,
"password_reset_url": url}
using the DEFAULT_HTTP_PROTOCOL
settings instead
2👍
Besides setting the "HTTPS" environment variable and SECURE_PROXY_SSL_HEADER
SECURE_SSL_REDIRECT, also seems that can be problem when rendering template and sending mail with EmailMultiAlternatives() when .txt body is used as is in adapter.py render_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
For example print(bodies[ext]) gave:
"To confirm this is correct, go to " https://127.0.0.1:8000/accounts/confirm-email/MjI:1kS0Mj:M5YfUf9-1Vg_TlgjVrK6vAtaLDE/ "
but on email is still http://
http://url7514.sitename/ls/click?upn=HJL2SSWV...
With most devices also this worked since should be redirected still to https://, but on some didn’t, so had to change in default templates/account/email/email_confirmation_message.txt to html extension,
after result :
To confirm this is correct, go to https://sitename/accounts/confirm-email/M...
- Django Rest Framework – AssertionError Fix your URL conf, or set the `.lookup_field` attribute on the view correctly
- Finding a Python Library to Mock a Database
- Localization: django-admin compilemessages skip venv
2👍
If you use django behind a proxy, you have to send https headers to django.
What works for me in apache2 was to put this on apache2
<VirtualHost *:443>
RequestHeader set X-Forwarded-Proto 'https' env=HTTPS
After adding headers mod:
a2enmod headers
And this on django setting.py:
USE_X_FORWARDED_HOST = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
With this all my build_absolute_uri started with https, and the same for templates, this include password recovery and auth mails.
- How do I save data from a ModelForm to database in django?
- Annotating SUM aggregation function leading to 'None' value in Django
- How do I generate models for an existing database in Django?
- ImageField() not saving images in ModelForm – Django/Python
- Django and service workers – serve "sw.js" at application's root url