DjangoRestFramework HTTPS链接路由器和视图集

时间:2014-03-09 08:11:17

标签: django ssl https django-rest-framework

是否有一种简单的方法可以修改视图集和路由器的开箱即用链接?

例如,在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)),

这会设置网址结构,如:

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

问题归结为建立链接是多么容易:

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

如果我停用了http /端口80并且只允许https /端口443,那么我的应用程序需要在无法打开http(因为我禁用端口80)后手动将https添加到链接。

1 个答案:

答案 0 :(得分:22)

DRF reverse使用request.build_absolute_uri(url)生成将构建网址"using the server variables available in this request."的网址,因此,如果请求为http,则生成的网址将为HTTP,而HTTPS也是如此。

如果你的django应用程序在反向代理后面运行,那么你需要配置SECURE_PROXY_SSL_HEADER设置。

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

但是,在设置时必须非常小心:

  

警告

     

如果设置了此选项,您可能会在您的网站中打开安全漏洞   不知道你在做什么。如果你没有设置它   应该。严重。

     

在设置之前确保满足以下所有条件(假设   上例中的值):

     

您的Django应用程序支持代理。你的代理剥离了   来自所有传入请求的 X-Forwarded-Proto 标头。换一种说法,   如果最终用户在其请求中包含该标头,则代理将会   丢弃它。您的代理设置了 X-Forwarded-Proto 标头并将其发送   到Django,但仅适用于最初通过HTTPS进入的请求。如果   如果不是这样,您应该将此设置设置为 None   并找到另一种确定HTTPS的方法,可能是通过自定义   中间件。

对于nginx,您可以使用以下配置设置X-Forwarded-Proto标头:

location / {
    # ... 
    proxy_set_header X-Forwarded-Proto $scheme;
}