Reputation: 101
I have a Django application hosted on AWS Elasticbeanstalk that is running a web service that a Chrome Extension is POSTing Gmail data to via XmlHttpRequest() via the extensions content scripts - not background.
As many may know who've done this, Chrome requires a secure endpoint for the web service. So there is a third-party validated cert on the server and CORS has been set up presumably correctly, because I'm getting the proper response headers in the preflight OPTIONS request. The issue I am having which makes the whole thing fall apart now is a 301 status code in the response which makes the CORS request fail - which you may also know causes the CORS process to fail per it's spec.
After some trial and error I've determined that the Django SSL setting:
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
which forwards HTTP requests to HTTPS if there is a proxy involved (presumably the way AWS is routing things) is causing the failure. However, if I don't have that setting Chrome throws a 'non-secure endpoint' error and kills the request. So it's a catch 22. Does anyone have any suggestions at getting around this? Here is my preflight OPTIONS request and response:
================REQUEST===========
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:www.example.com
Origin:chrome-extension://p1312312dd1d1d1d1d1d3
Referer:https://mail.google.com/mail/u/0/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36
================RESPONSE===========
Access-Control-Allow-Headers:content-type
Access-Control-Allow-Methods:POST, OPTIONS
Access-Control-Allow-Origin:*
Connection:keep-alive
Content-Language:en
Content-Length:0
Content-Type:text/html; charset=utf-8
Date:Sat, 17 Oct 2015 17:07:13 GMT
Location:https://www.example.com
Server:Apache/2.4.12 (Amazon) mod_wsgi/3.5 Python/2.7.9
Vary:Accept-Language,Cookie
X-Frame-Options:SAMEORIGIN
Upvotes: 4
Views: 11814
Reputation: 101
I was finally able to resolve with a combination of a few things:
Removing SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
from the Django settings.py and instead using sslify to force https redirect in place of that.
Making sure the trailing '/' was present in the original CORS request destination url which also causes a 3xx redirect.
Doubling up the headers on the server side of AWS by adding 'Access-Control-Allow-Origin': '*','Access-Control-Allow-Methods': 'POST, OPTIONS','Access-Control-Allow-Headers': 'content-type',
to the AWS_HEADERS setting in Django's settings.py.
Adding another, likely redundant, https force within wsgi by adding os.environ['wsgi.url_scheme'] = 'https'
to Django's settings.py. You can also do this by adding another https force os.environ['https'] = "on"
within wsgi.py.
All of these things together proved to work, the last one is most likely redundant but sometimes the request would fail to be recognized as https without it. In all likelihood this could have been due to caching, but better safe than sorry.
Hopefully this helps someone like me who was dealing with this issue for a while without any clear solution.
Upvotes: 6