如何修复 Sinatra 在 nginx 下将 https 重定向到 http
我有一个在 nginx 中运行的 Sinatra 应用程序(使用 Thin 作为反向代理),并且我在 Sinatra 中使用 redirect '/
语句。但是,当我在 https 下访问该网站时,这些重定向会将我发送到 http://localhost/
而不是 https://localhost/
code> 正如他们应该的那样。
目前,nginx 使用此命令 proxy_pass http://thin_cluster
将控制权传递给 Thin,其中 thin_cluster
是
upstream thin_cluster { server unix:/tmp/thin.cct.0.sock; }
我该如何解决这个问题?
I have a Sinatra app running in nginx (using thin as a back-proxy) and I'm using redirect '/<path>'
statements in Sinatra. However, when I access the site under https, those redirects send me to http://localhost/<path>
rather than to https://localhost/<path>
as they should.
Currently, nginx passes control to thin with this command proxy_pass http://thin_cluster
, where thin_cluster
is
upstream thin_cluster { server unix:/tmp/thin.cct.0.sock; }
How can I fix this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为了让 Sinatra 正确组装用于重定向的 url,它需要能够确定请求是否使用 ssl,以便可以使用
http
或https 视情况而定。
显然,对 Thin 的实际调用并未使用 ssl,因为这是由前端 Web 服务器处理的,并且代理请求是明文的。因此,我们需要一种方法来告诉 Sinatra,即使它实际上没有使用 ssl,它也应该将请求视为安全的。
最终确定请求是否应被视为安全的代码位于
Rack::Request#ssl?
和Rack::Request#scheme
方法。scheme
方法检查env
哈希值以查看是否存在多个条目之一。其中之一是HTTP_X_FORWARDED_PROTO
,它对应于X-Forwarded-Proto
HTTP 标头。如果设置了此项,则该值将用作协议方案(http
或https
)。因此,如果我们在请求从 nginx 代理到后端时将这个 HTTP 标头添加到请求中,Sinatra 将能够正确确定何时重定向到
https
。在 nginx 中,我们可以使用proxy_set_header
向代理请求添加标头,该方案可在$scheme
变量。因此,将该行添加
到 nginx 配置中的
proxy_pass
行之后应该可以使其正常工作。In order for Sinatra to correctly assemble the url used for redirects, it needs to be able to determine whether the request is using ssl, so that the redirect can be made using
http
orhttps
as appropriate.Obviously the actual call to thin isn't using ssl, as this is being handled by the front end web server, and the proxied request is in the clear. We therefore need a way to tell Sinatra that it should treat the request as secure, even though it isn't actually using ssl.
Ultimately the code that determines whether the request should be treated as secure is in the
Rack::Request#ssl?
andRack::Request#scheme
methods. Thescheme
methods examines theenv
hash to see if one of a number of entries are present. One of these isHTTP_X_FORWARDED_PROTO
which corresponds to theX-Forwarded-Proto
HTTP header. If this is set, then the value is used as the protocol scheme (http
orhttps
).So if we add this HTTP header to the request when it is proxied from nginx to the back end, Sinatra will be able to correctly determine when to redirect to
https
. In nginx we can add headers to proxied requests withproxy_set_header
, and the scheme is available in the$scheme
variable.So adding the line
to the nginx configuration after the
proxy_pass
line should make it work.您可以在 nginx 层强制所有链接都转到 https。
在 nginx.conf 中:
这也很好地确保您的请求始终是 https
You can force all links to go to https in the nginx layer.
in nginx.conf:
This is good to have too to assure that your requests are always https