3

Using sample Django Projects and my Django Rest Framework project, I can deploy to app engine without issue.

I can access the site via both https://myappnamehere.appspot.com and the http:// version as well.

However, I'm seemingly unable to force it to only allow HTTPS.

Attempt 1: In my Django settings, I try to set :

SECURE_SSL_REDIRECT = True 

This ends with my project no longer showing up on app engine, with AppEngine reporting that I should try again in 30 minutes

Attempt 2: In app.yaml, I follow the advice from here and other stack overflow threads by adding this:

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

This also ended up with the routing seemingly messed up, and all my URLs no longer routed thru the django router as expected.

What is inside the wsgi: import os

from django.core.wsgi import get_wsgi_application os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myapplication.settings.settings") application = get_wsgi_application() 

Attempt 3: Sorry, I forgot to mention I tried it with secure always, and it ends up with my site being unable to load again as well.

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

3 Answers 3

3

Just add a secure parameter to the app.yaml file.

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

See Configuring Secure URLs in app.yaml

Sign up to request clarification or add additional context in comments.

4 Comments

sorry, forgot to mention that I tried that as well. Instead, my site doesn't load at all anymore with it.
Does your SSL cert cover the naked domain as well as the www subdomain? Did you try both?
@GAEfan, I'm not even trying a custom domain for SSL anymore, even the deploying it on an appengine instance doesn't work. Setting Django Settings files and app.yaml doesn't seem to do anything except cause the site to report "Error: Server Error The service you requested is not available yet. Please try again in 30 seconds."
The proper syntax in your app.yaml is - url: /.*. You will want to check your logs in the cloud console, to see the stack trace for the 500 error. It should give you a hint.
1

As Bravin said, a simple method is to add secure: always to app.yaml. However, if you care about consistent subdomains (e.g., always going to the www. address), then you would want to write your own middleware to redirect to 'https://www....`

Consistent subdomains is an SEO thing. Search engines can count the naked domain and the www. domain as distinct addresses. Also, some SSL certificates only cover one subdomain (i.e. www.) and not the naked domain.

If you write your own middleware, make sure you exempt tasks, crons, backends, etc., or they might get stuck returning 301s. Also exempt your localhost requests for development.

Also, there is still a small percentage of users with older browsers or operating systems that cannot be served SSL using the SNI protocol. What do you do with those? In this example, we still serve them secure content, using the appspot.com certificate.

Example middleware:

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 

Be sure to add 'path_to.my_middleware.ForceHttps' to MIDDLEWARE_CLASSES in SETTINGS.py

Comments

1

All the answers here helped guide me on the right path. This is the final app.yaml setup that worked for my project after a million attempts. (I was also trying to reduce appengine costs by limiting the resources

# [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] 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.