Tastypie POST位置HTTPS与HTTP

时间:2012-09-19 03:51:15

标签: django http heroku https tastypie

当我将新资源发布到我的RESTful Tastypie API时,我创建了一个资源并获得了这样的201响应:

HTTP/1.1 201 CREATED
Content-Type: text/html; charset=utf-8
Date: Wed, 19 Sep 2012 01:02:48 GMT
Location: http://example.com/api/v1/resource/12/
Server: gunicorn/0.14.6
Content-Length: 0
Connection: keep-alive

大!除了我发布到HTTPS URL并希望获得HTTPS Location标头。如何配置tastypie来执行此操作?

加成

我正在使用一些中间件强制使用SSL,但我不认为这是导致此问题的原因。无论如何它在这里:

class SSLifyMiddleware(object):
    # Derived from https://github.com/rdegges/django-sslify
    def process_request(self, request):
        if not any((not settings.FORCE_SSL, request.is_secure(), request.META.get('HTTP_X_FORWARDED_PROTO', '') == 'https')):
            url = request.build_absolute_uri(request.get_full_path())
            secure_url = url.replace('http://', 'https://')
            return HttpResponseRedirect(secure_url)

加成

这是一个Heroku应用程序。

1 个答案:

答案 0 :(得分:5)

根据我们的确定,以http代替https开头的网址的原因是request.is_secure()False

导致request.is_secure()False的原因有多种,例如,在使用HTTP连接到服务器的负载均衡器或反向代理之后,而客户端和负载均衡器/反向代理之间的连接是使用SSL制作。

如果您位于代理或负载均衡器之后,请查看SECURE_PROXY_SSL_HEADER的文档,这是一些解决方案:

  

如果您的Django应用程序位于代理服务器后面,代理可能会“吞咽”请求为HTTPS,使用代理和Django之间的非HTTPS连接。在这种情况下,is_secure()将始终返回False - 即使对于最终用户通过HTTPS发出的请求也是如此。

     

在这种情况下,您需要配置代理以设置自定义HTTP标头,告知Django请求是否通过HTTPS传入,并且您需要设置SECURE_PROXY_SSL_HEADER以便Django知道要查找的标头。