Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DjangoRestFramework HTTPS Links With Routers and Viewsets

Is there an easy way to modify the links out-of-the-box for viewsets and routers?

For example, in urls.py:

from rest_framework import viewsets, routers
...
class Activity_TypeViewSet(viewsets.ModelViewSet):
    model = Activity_Type
...
router.register(r'activity_types', Activity_TypeViewSet)
...
url(r'^', include(router.urls)),

This sets up url structure like:

{"activity_types": "http://odd.quantdevgroup.com/activity_types/"}

The question comes down to how easy it is to make the link:

{"activity_types": "**https**://odd.quantdevgroup.com/activity_types/"}

If I deactivated http/ port 80 and only allowed https/ port 443 then my app requires manually adding https to the link after it fails to open http (because I disabled port 80).

like image 493
sahutchi Avatar asked Mar 09 '14 08:03

sahutchi


People also ask

What are ViewSets?

A ViewSet class is simply a type of class-based View, that does not provide any method handlers such as . get() or . post() , and instead provides actions such as . list() and . create() .

How do you use a router in DRF?

Routers are used with ViewSets in django rest framework to auto config the urls. Routers provides a simple, quick and consistent way of wiring ViewSet logic to a set of URLs. Router automatically maps the incoming request to proper viewset action based on the request method type(i.e GET, POST, etc).

How do I enable https in Django REST framework?

You need to run a real webserver like Apache to start serving HTTPS requests, or at least install stunnel (http://stackoverflow.com/questions/8023126/how-can-i-test-https-connections-with-django-as-easily-as-i-can-non-https-connec). You could also do the redirection in Django by looking at HttpRequest.

What is difference between APIView and Viewset?

APIView allow us to define functions that match standard HTTP methods like GET, POST, PUT, PATCH, etc. Viewsets allow us to define functions that match to common API object actions like : LIST, CREATE, RETRIEVE, UPDATE, etc.


1 Answers

DRF reverse uses request.build_absolute_uri(url) to generate urls which will build URLs "using the server variables available in this request.", so if the request is http, generated URLs will be HTTP and same thing for HTTPS.

If your django app running behind a reverse proxy, then you need to configure SECURE_PROXY_SSL_HEADER setting.

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

However, you have to be really careful when setting this:

Warning

You will probably open security holes in your site if you set this without knowing what you’re doing. And if you fail to set it when you should. Seriously.

Make sure ALL of the following are true before setting this (assuming the values from the example above):

Your Django app is behind a proxy. Your proxy strips the X-Forwarded-Proto header from all incoming requests. In other words, if end users include that header in their requests, the proxy will discard it. Your proxy sets the X-Forwarded-Proto header and sends it to Django, but only for requests that originally come in via HTTPS. If any of those are not true, you should keep this setting set to None and find another way of determining HTTPS, perhaps via custom middleware.

For nginx, you can set X-Forwarded-Proto header using this configuration:

location / {
    # ... 
    proxy_set_header X-Forwarded-Proto $scheme;
}
like image 155
almalki Avatar answered Sep 22 '22 19:09

almalki