6

当我向我的 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 并希望Location返回一个 HTTPS 标头。我怎样才能配置tastepie来做到这一点?

添加

我正在使用一些中间件来强制使用 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 应用程序。

4

1 回答 1

5

http正如我们已经确定的那样,以代替开头的 URL 的原因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 知道要查找的标头。

于 2012-09-19T17:30:33.063 回答