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).

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;
}

Need Your Help

C# Pass Lambda Expression as Method Parameter

c# linq lambda

I have a lambda expression that I'd like to be able to pass around and reuse. Here's the code:

Moment.js - How To Detect Daylight Savings Time And Add One Day

javascript date momentjs

I need to create Date Objects from strings of Date data for every hour of every day since the year 2000.