martinsam / django-heroism Goto Github PK
View Code? Open in Web Editor NEWThis project forked from rossdakin/django-heroism
A way for Django to detect an HTTPS request when proxied through a front-end server.
This project forked from rossdakin/django-heroism
A way for Django to detect an HTTPS request when proxied through a front-end server.
django-heroism Nomenclature ------------ Please pardon the name. HEROISM is an (admittedly somewhat forced) acronym for: Header Explicates Request Object's is_secure Method I was so happy when I found a working solution to this problem, that I indeed viewed this little app as a hero. What problem? you ask? Read on, dear friend. The Problem ----------- django-heroism applies to this use case: * you need to use secure (HTTPS) pages on your Django-powered site, AND * you proxy Django requests from a "front-end server" (e.g. nginx) to a "back-end server" (e.g. Apache) The problem with this setup is that Django doesn't know if the request was secure or not, because the request does not get propagated from the front-end server to the back-end server using its original schema. For example, a secure request probably looks like this: Browser <=== HTTPS ===> nginx <=== HTTP ===> Apache and an insecure request probably looks like this: Browser <=== HTTP ===> nginx <=== HTTP ===> Apache By the time the request hits Apache, it's _always_ using HTTP (unless you host your front-end server and back-end servers on different networks, in which case you might want to secure the connection between them, and the request would appear to _always_ be HTTPS). As the programmer of a secure website, you will likely find this problematic. The Remedy ---------- django-heroism solves this problem by passing along an extra header from the front-end server to the back-end server, explicating whether or not the connection is secure, like this: Browser <=== HTTPS ===> nginx <=== HTTP ===> Apache < new_header > More accurately, django-heroism _detects_ the header and uses it to tell Django whether the original request was secure or insecure, by overriding the request method's is_secure() method. You must setup this new header yourself. Justification ------------- Other implementation options exist, but they may vary depending on your specific deployment setup (mod-wsgi, vs. mod-python, vs. *.cgi, etc.). I chose this method because it is fairly deployment-agnostic; all web servers understand headers and typically let you customize them fairly painlessly. Having said that, be sure to read the installation instructions. Installation ------------ 1) Add the django-heroism app to your PYTHONPATH. 2) Add the HeroismMiddleware to your list of middleware, ideally near the top so that other middleware can rely on request.is_secure() being accurate: MIDDLEWARE_CLASSES = ( 'heroism.middleware.HeroismMiddleware', ... ) Add the HeroismMiddleware to your list of middleware TEMPLATE_CONTEXT_PROCESSORS = ( 'heroism.context_processors.ssl_media', ... ) 3) Adjust the header name/value defaults in django-heroism/heroism/__init__.py if you don't like them. 4) Configure your front-end server to send along the new header. Please see django-heroism/nginx-conf-sample for an example (NOT a drag-n-drop example though; make sure you have a thorough knowledge of your deployment config). Pay particular attention to the following line in mysite.conf: proxy_set_header X-Forwarded-Protocol "https"; You could choose to define this with a value of "http" in your port 80 block or simply not send the header for insecure requests and let the middleware default to insecure. Django Dev Server ----------------- django-heroism should work just fine with the Django development server, since it will default to insecure, and the dev server doesn't speak HTTPS anyway. Acknowledgements ---------------- I derived this idea from the seemingly de-facto solution to the Rails equivalent to this problem. I forget where I first read about it, but if your blog is on the first page of Google results for some combination of the terms: (nginx, apache, proxy, https, secure, french toast in palo alto open late) then I probably stumbled upon it; many thanks! Maybe some day we can get a version of this worked into Django core or contrib, as it is in Rails. The Future ---------- I would love to get a better version of this worked into core or contrib if there's enough interest (and there should be, because the two-server proxy technique seems quite popular, and because everyone _should_ be using SECURE_COOKIES = True, right? right?). Plus it's built in to Rails.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.