Permanently Redirect http to https on Google App Engine Flexible with Django

谁都会走 提交于 2021-02-10 12:14:09

问题


I'm working on a project that uses Google Cloud Platform's App Engine in the Python 3 Flexible Environment using Django, and I'm trying to permanently redirect all requests over http to https for all routes, but so far have not been successful. I can access the site over https, but only if explicitly written in the address bar.

I've looked at this post: How to permanently redirect `http://` and `www.` URLs to `https://`? but did not find the answer useful.

The app works properly in every sense except for the redirecting. Here is my app.yaml file:

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

runtime_config:
  python_version: 3
# [END runtime]

In myproject/settings.py I have these variables defined:

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

On my local machine, when I set SECURE_SSL_REDIRECT to True, I was redirected to https properly, even though SSL is not supported on localhost. In production, I am still able to access the site using just http.

Is there something I'm missing or doing wrong to cause the redirect not to happen?


回答1:


Setting secure in app.yaml only works for GAE Standard but not in Flexible. The app.yaml docs for Flexible do not mention this key at all.

You will probably have to do it on application level by inspecting the value of the X-Forwarded-Proto header. It will be set to https if the request to your app came by HTTPS. You can find more info on environment-provided headers in Flexible environment in the docs here.




回答2:


Make sure you have SecurityMiddleware and CommonMiddleware enabled, and assign a Base_URL:

settings.py:

MIDDLEWARE_CLASSES = (
    ...
    'django.middleware.security.SecurityMiddleware'
    'django.middleware.common.CommonMiddleware',    
)

BASE_URL = 'https://www.example.com'

Or, you could write your own middleware:

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:


The issue is the header name. When accessing Django through a WSGI server, you should use the X-Forwarded-Proto header instead of the HTTP_X_FORWARDED_PROTO.

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




回答4:


I had a similar problem and tried a number changes both in the app.yaml and also in settings.py for a custom domain (with the default ssl cert supplied by GAE).

Through trial and error I found that in settings.py updating the allowed hosts to the appropriate domains had the desired result:

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

Update: I am no longer sure the above is the reason as on a subsequent deploy the above was rejected and I was getting a hosts error. However the redirect is still in place... :(

Before this change I was able to switch between http:// and https:// manually in the address bar now it redirects automaticlly.



来源:https://stackoverflow.com/questions/52029939/permanently-redirect-http-to-https-on-google-app-engine-flexible-with-django

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!