【问题标题】:Permanently Redirect http to https on Google App Engine Flexible with Django使用 Django 将 Google App Engine 上的 http 永久重定向到 https
【发布时间】:2019-02-01 10:31:37
【问题描述】:

我正在开发一个使用 Django 在 Python 3 灵活环境中使用 Google Cloud Platform 的 App Engine 的项目,并且我正在尝试将所有路由上的所有请求永久重定向到 httphttps,但是这样远远没有成功。我可以通过https 访问该站点,但前提是在地址栏中明确写入。

我看过这篇帖子:How to permanently redirect `http://` and `www.` URLs to `https://`?,但没有找到有用的答案。

除了重定向之外,该应用在各个方面都能正常工作。这是我的app.yaml 文件:

# [START runtime]
runtime: python
env: flex
entrypoint: gunicorn -b :$PORT myproject.wsgi

runtime_config:
  python_version: 3
# [END runtime]

myproject/settings.py 我定义了这些变量:

SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SECURE_PROXY_SSL_HEADER = ('HTTP-X-FORWARDED-PROTO', 'https')

在我的本地机器上,当我将SECURE_SSL_REDIRECT 设置为True 时,我被正确地重定向到https,即使本地主机不支持 SSL。在生产中,我仍然可以使用 http 访问该站点。

是否有什么我遗漏或做错了导致重定向不发生?

【问题讨论】:

    标签: python django google-app-engine ssl google-cloud-platform


    【解决方案1】:

    在 app.yaml 中设置 secure 仅适用于 GAE 标准,但不适用于灵活。 app.yaml docs for Flexible 根本没有提到这个键。

    您可能必须通过检查 X-Forwarded-Proto 标头的值在应用程序级别执行此操作。如果对您的应用程序的请求来自 HTTPS,它将被设置为https。您可以在文档here 的灵活环境中找到有关环境提供的标头的更多信息。

    【讨论】:

    • 谢谢。您为我指明了正确的方向,但我仍然遇到麻烦。我已经更新了我的问题。
    • 所以你指出的是问题的一部分,我最终使用了SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') 设置。
    • 您是如何解决问题的。我遇到了同样的问题。
    【解决方案2】:

    确保您已启用SecurityMiddlewareCommonMiddleware,并分配Base_URL

    settings.py:

    MIDDLEWARE_CLASSES = (
        ...
        'django.middleware.security.SecurityMiddleware'
        'django.middleware.common.CommonMiddleware',    
    )
    
    BASE_URL = 'https://www.example.com'
    

    或者,您可以编写自己的中间件:

    MIDDLEWARE_CLASSES = (
        ...
        'core.my_middleware.ForceHttps',
    )
    
    BASE_URL = 'https://www.example.com'
    

    my_middleware.py:

    from django.http import HttpResponsePermanentRedirect
    
    class ForceHttps(object):
    
        def process_request(self, request):
    
            if not (request.META.get('HTTPS') == 'on' and settings. BASE_URL == 'https://' + request.META.get('HTTP_HOST') ):
                return HttpResponsePermanentRedirect(settings. BASE_URL + request.META.get('PATH_INFO'))
            else:
                return None
    

    【讨论】:

      【解决方案3】:

      问题是标题名称。通过 WSGI 服务器访问 Django 时,应使用 X-Forwarded-Proto 标头而不是 HTTP_X_FORWARDED_PROTO

      见:Why does django ignore HTTP_X_FORWARDED_PROTO from the wire but not in tests?

      【讨论】:

        【解决方案4】:

        我遇到了类似的问题,并尝试在 app.yaml 和 settings.py 中对自定义域进行一些更改(使用 GAE 提供的默认 ssl 证书)。

        通过反复试验,我发现在 settings.py 中将允许的主机更新到适当的域会产生预期的结果:

        ALLOWED_HOSTS = ['https://{your-project-name}.appspot.com','https://www.yourcustomdomain.com'] 
        

        更新:我不再确定上述是原因,因为在后续部署中上述被拒绝并且我收到主机错误。但是重定向仍然存在...... :(

        在此更改之前,我可以在地址栏中手动切换 http:// 和 https://,现在它会自动重定向。

        【讨论】:

          【解决方案5】:

          为了在测试时在 App Engine Flexible 和您的本地机器上都能正常工作,您应该在 settings.py 中设置以下内容

          if os.getenv('GAE_INSTANCE'):
              SECURE_SSL_REDIRECT = True
              SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
          else:
              # Running on your local machine
              SECURE_SSL_REDIRECT = False
              SECURE_PROXY_SSL_HEADER = None
          

          当您在应用引擎上时,您需要做的就是确保重定向正确发生。

          注意:如果您使用的是老式应用程序引擎 cron 作业(通过 cron.yaml),那么您将需要开始使用经过改进的云调度程序。应用引擎 cron 作业不正确支持重定向到 HTTPS,但您可以轻松地使用云调度程序。

          【讨论】:

          • 不管你有没有SECURE_SSL_REDIRECT = True,我认为设置SECURE_PROXY_SSL_HEADER没有任何害处,所以我建议不要使用if/else声明SECURE_SSL_REDIRECT = bool(os.getenv('GAE_INSTANCE'))'
          • @DragonBobZ 看起来是正确的,我还没有测试过,但这应该很好用。谢谢!
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-08-04
          • 1970-01-01
          • 1970-01-01
          • 2016-09-06
          • 2021-10-09
          • 1970-01-01
          相关资源
          最近更新 更多