Django Project不能强制Google Appengine重定向到https

时间:2017-01-11 03:40:11

标签: python django google-app-engine django-rest-framework

使用示例Django Projects和我的Django Rest Framework项目,我可以毫无问题地部署到app引擎。

我也可以通过https://myappnamehere.appspot.com和http://版本访问该网站。

但是,我似乎无法强制它只允许HTTPS。

尝试1: 在我的Django设置中,我尝试设置:

SECURE_SSL_REDIRECT = True

这结束了我的项目不再出现在app引擎上,AppEngine报告我应该在30分钟内再试一次

尝试2: 在app.yaml中,我遵循here的建议 和其他堆栈溢出线程添加:

handlers:
- url: /*
  script: myapplication.wsgi.application

这最终导致路由看起来搞砸了,我的所有URL都不再按预期路由到django路由器。

wsgi里面是什么:     import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myapplication.settings.settings")
application = get_wsgi_application()

尝试3:对不起,我忘了提到我一直尝试安全,最终我的网站也无法再次加载。

handlers:
- url: /*
  script: myapplication.wsgi.application
  secure: always

3 个答案:

答案 0 :(得分:3)

只需在app.yaml文件中添加安全参数即可。

handlers:
- url: /*
  script: anyfile.py
  secure: always

See Configuring Secure URLs in app.yaml

答案 1 :(得分:1)

正如Bravin所说,一种简单的方法是将secure: always添加到app.yaml。但是,如果您关心一致的子域(例如,总是转到www.地址),那么您可能希望编写自己的中间件以重定向到&#39; https://www ....`< / p>

一致的子域名是SEO的东西。搜索引擎可以将裸域和www.域计为不同的地址。此外,某些SSL证书仅涵盖一个子域(即www.),而不是裸域。

如果您编写自己的中间件,请确保您免除任务,crons,后端等,否则他们可能会因为返回301而被卡住。同时免除本地主机的开发请求。

此外,仍有一小部分使用旧版浏览器或操作系统的用户无法使用SNI协议提供SSL服务。那你怎么办?在此示例中,我们仍使用appspot.com证书为其提供安全内容。

示例中间件:

from django.http import HttpResponsePermanentRedirect
import os
import logging

class ForceHttps(object):
    '''
    We want all requests to go to https://www.{mysite}.com
    except: Cron, Taskqueue, backend jobs, dev server

    test this against secure: always in app.yaml

    In this example, we redirect non-SNI compatible browsers to the secure appspot.com address
    '''

    def process_request(self, request):

        user_agent = request.META.get('HTTP_USER_AGENT', 'fake')

        if (    'AppEngine-Google' in user_agent or 
                'mybackendmodule' in request.META.get('CURRENT_MODULE_ID') or
                'dot-appname' in request.META.get('HTTP_HOST') or
                 os.environ.get('SERVER_SOFTWARE', '').lower().startswith('devel') ):
            return None

        # for non-SNI SSL browsers, we send to appspot domain:
        if (
                ((('Windows NT 5.1' in user_agent) or ('Windows XP' in user_agent)) and (('MSIE' in user_agent) or ('Safari' in user_agent) or ('Chrome' in user_agent))) or        # XP with most browsers
                (('MSIE 6' in user_agent) or ('MSIE 5' in user_agent)) or                                                 # any version of IE6 or 5
                ((('Windows NT 6.1' in user_agent) or ('Windows NT 6.2' in user_agent)) and ('webDAV' in user_agent)) or  # IE7 or 8 with webDAV
                (('Android 2.' in user_agent) or ('Android 1.' in user_agent)) ):                                         # android 2.x

            logging.info('Redirecting to appspot.  SNI incompatibility detected: ' + user_agent )

            return HttpResponsePermanentRedirect("https://{appname}.appspot.com" + request.META.get('PATH_INFO'))



        # for SNI compatible browsers:
        if request.META.get('HTTPS') == 'off' or 'www' not in request.META.get('HTTP_HOST') :
            return HttpResponsePermanentRedirect("https://www.{mysite}.com" + request.META.get('PATH_INFO'))

        return None

请务必在'path_to.my_middleware.ForceHttps'

中将MIDDLEWARE_CLASSES添加到SETTINGS.py

答案 2 :(得分:1)

这里的所有答案都有助于我走上正确的道路。这是最终的app.yaml设置,经过一百万次尝试后,我的项目才有效。 (我还试图通过限制资源来降低发动机成本

# [START runtime]
vm: true
runtime: custom
service: backend-dev

manual_scaling:
   instances: 1

resources:
  cpu: .5
  memory_gb: 0.6
  disk_size_gb: 10

handlers:

- url: /static
  static_dir: static

- url: /.*
  script: myapplication.wsgi.py
  secure: always

# [END runtime]