You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django重置密码视图中protocol返回http而非https问题排查

Django密码重置邮件中protocol返回http而非https的问题排查

问题场景

我在基于django/postgresql/docker的应用中使用Django registration模块,重写了密码重置视图:

class ResetPasswordView(SuccessMessageMixin, PasswordResetView):

    template_name = 'registration/password_reset_form.html'
    email_template_name = 'registration/password_reset_email.html'
    subject_template_name = 'registration/password_reset_subject.txt'
    success_message = "We've emailed you instructions for setting your password, " \
                      "if an account exists with the email you entered. You should receive them shortly." \
                      " If you don't receive an email, " \
                      "please make sure you've entered the address you registered with, and check your spam folder."
    success_url = reverse_lazy('home')

同时使用如下重置密码邮件模板:

Someone asked for password reset for email {{ email }}. 
Follow the link below:
{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}

PS : Please do not reply to this email

但邮件模板上下文的protocol返回http而非https,请问问题出在哪里?

问题原因及解决方案

  • 未配置Django安全相关设置:
    Django默认根据请求的协议生成protocol值,如果生产环境使用HTTPS但Django未感知到真实请求协议,就会返回http。需要在settings.py中添加以下配置:

    # 强制跳转至HTTPS
    SECURE_SSL_REDIRECT = True
    # 让Django识别反向代理传递的HTTPS协议头
    SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
    # 标记SESSION和CSRF Cookie仅通过HTTPS传输
    SESSION_COOKIE_SECURE = True
    CSRF_COOKIE_SECURE = True
    

    其中SECURE_PROXY_SSL_HEADER专门用于应用部署在反向代理(如Nginx、Docker容器代理)之后的场景,确保Django能获取到真实的请求协议。

  • 自定义视图未强制指定protocol:
    可以在重写的ResetPasswordView中直接重写get_protocol方法,固定返回https:

    class ResetPasswordView(SuccessMessageMixin, PasswordResetView):
        # 原有属性配置...
        
        def get_protocol(self):
            return 'https'
    

    这种方式适合无需根据环境动态切换协议的场景,比如固定使用HTTPS的生产环境。

  • Docker反向代理未传递协议头:
    如果使用Docker部署应用,反向代理(如Nginx)需要正确传递请求的协议头信息。示例Nginx配置需添加:

    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $remote_addr;
    

    确保Django能通过X-Forwarded-Proto头获取到真实的HTTPS协议。


内容的提问来源于stack exchange,提问作者Mereva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 17:15:53