4

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

从我的请求标头:

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

从我的回复标题中:

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

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

所有帮助表示赞赏!

更新: 这实际上与 Tastypie 没有任何关系,这是因为服务器/代理配置。有关解决方案的详细信息,请参见下面的答案。

4

1 回答 1

6

原因很简单:在您的情况下似乎request.is_secure()返回False,因此 URL 是使用http而不是构造的https.

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

要解决这个问题,您可以查看SECURE_PROXY_SSL_HEADERDjango 中的设置,它定义了指示与代理或负载均衡器建立的 SSL 连接的标头:

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

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

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

于 2012-09-27T17:34:26.133 回答