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]
3π
Just add a secure parameter to the app.yaml file.
handlers:
- url: /*
script: anyfile.py
secure: always
- [Django]-Django module object is not iterable
- [Django]-Two or More Django Projects in Same Droplet via Subdomain
- [Django]-Django tutorial : TypeError at /polls/3/vote/ reverse() takes no keyword arguments
- [Django]-How to customize Haystack's SearchView to accept addtional URL parameters?
- [Django]-Django admin login returns Forbidden 403 CSRF verification failed. Request aborted
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
- [Django]-Override ModelViewSet's queryset with filter backends applied
- [Django]-How do you produce/create tables in Geraldo Reports?
- [Django]-Amazon ELB + Django HTTPS issues
- [Django]-Django admin not working with custom auth backend