对Tastypie的POST请求返回非SSL位置标头

时间:2012-09-27 17:27:38

标签: python django ssl tastypie

我正在对我的Tastypie api发出POST请求,这会创建一个资源。 它通常通过响应中的Location标头返回资源uri。 我遇到的问题是Location标头包含一个非ssl网址,即使我的初始请求(以及我的整个应用程序)都在https下。

来自我的请求标题:

URL: https://example.com/api/v1/resource/

来自我的回复标题:

Location: http://example.com/api/v1/resource/80/

因为这是一个并不总是在ssl下运行的可重用应用程序,所以我不想硬编码丑陋的字符串替换。此外,已经有一个301重定向,从http到https,但我不希望重定向发生。

所有帮助表示赞赏!

更新 这实际上与Tastypie没有任何关系,这是因为服务器/代理配置。请参阅下面的答案以获取解决方案详情。

1 个答案:

答案 0 :(得分:6)

原因很简单:看似request.is_secure()在您的案例中返回False,因此网址是使用http而不是https构建的。

有几种解决方案,但您应首先找到导致request.is_secure()返回False的原因。我打赌你在一些代理或负载均衡器后面运行。如果您没有更改URL生成背后的逻辑,那么这可能是您的问题的原因。

要解决此问题,您可以查看SECURE_PROXY_SSL_HEADER setting in Django,它定义表示与代理或负载均衡器建立的SSL连接的标头:

  

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

     

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

但是,如果您正在设计一个可重复使用的应用程序,并且上述情况在您的情况下是正确的,请确保它不是不同的东西。如果您确定是这种情况,那么请将其留给用户 - 负责安全请求指示的标头应该由显式设置,只有使用您的应用程序的程序员才能设置。否则,这可能意味着安全问题。