当我将新资源发布到我的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应用程序。
答案 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知道要查找的标头。