Rails 应用程序 HTTP 到 HTTPS 重定向不适用于公开的 API

Posted

技术标签:

【中文标题】Rails 应用程序 HTTP 到 HTTPS 重定向不适用于公开的 API【英文标题】:Rails App HTTP to HTTPS Redirect Not Working for Exposed API 【发布时间】:2015-05-23 23:11:01 【问题描述】:

我正在构建一个包含前端网站和公开 API 的 Rails 4 应用程序。该 API 用作移动应用和桌面应用的后端。

我在 Heroku 上部署了应用程序。因为该网站有一个订购系统,所以我决定在全球范围内强制使用 ssl。当我发出 HTTP 请求时,网站成功地将我重定向到 HTTPS。

但是,当我从命令行使用 cURL 向公开的 API 发出 HTTP 请求时,我没有得到预期的响应。相反,我在 Heroku 日志中看到了 301 状态消息(见下文)。当我通过 HTTPS 使用 cURL 发出相同的请求时,一切正常,并且我得到了成功的响应。

因此,除了 API 之外,HTTP 请求在任何地方都成功地重定向到 HTTPS。但是,API 仍能正确响应 HTTPS 请求。

我做错了什么?如何允许用户向我的 API 发出 HTTP 请求,而只是像在应用程序的其余部分一样通过 HTTPS 重定向他们的请求?这没有意义吗?

我正在使用它在我的控制器中强制 https:

# /app/controllers/api/v1/pairings_controller.rb
before_filter :redirect_to_https
...
def redirect_to_https
  redirect_to :protocol => "https://" unless (request.ssl? || request.local?)
end

我也试过了

# config/application.rb
config.force_ssl = (ENV["ENABLE_HTTPS"] == "yes")
config.ssl_options = hsts: expires: 1209600

Heroku 日志:

使用 HTTP 失败:

2015-03-20T13:40:26.590091+00:00 heroku[router]: at=info method=POST path="/api/v1/pairing/request" host=xxx.herokuapp.com request_id=f832239b-d352-43ed-b5c6-e8d6c9f7c242 fwd="23.27.14.153" dyno=web.1 connect=1ms service=11325ms status=200 bytes=540
2015-03-20T13:40:26.585221+00:00 app[web.1]: Completed 200 OK in 4954ms (Views: 0.3ms | ActiveRecord: 20.3ms)
2015-03-20T13:45:43.502413+00:00 heroku[router]: at=info method=POST path="/api/v1/pairing/request" host=xxx.herokuapp.com request_id=dd633b85-a70b-4a2d-bb39-b450972bb2ab fwd="23.27.14.153" dyno=web.1 connect=1ms service=1739ms status=301 bytes=211

使用 HTTPS 成功:

2015-03-20T13:40:19.113646+00:00 app[web.1]: Started POST "/api/v1/pairing/request" for 23.27.14.153 at 2015-03-20 13:40:18 +0000
2015-03-20T13:40:21.064630+00:00 app[web.1]: Processing by Api::V1::PairingsController#post_pairing_request as JSON
2015-03-20T13:40:21.631071+00:00 app[web.1]:   Parameters: "flags"=>"xxx", "otp"=>"xxx", "phone"=>"xxx", "pin"=>"xxx", "user"=>"address"=>"xxx", "city"=>"Ripley", "email"=>"xxx", "name"=>"xxx", "state"=>"xxx", "zip"=>"xxx", "pairing"=>"pin"=>"xxx", "phone"=>"xxx", "otp"=>"xxx"
2015-03-20T13:40:26.590091+00:00 heroku[router]: at=info method=POST path="/api/v1/pairing/request" host=xxx.herokuapp.com request_id=f832239b-d352-43ed-b5c6-e8d6c9f7c242 fwd="23.27.14.153" dyno=web.1 connect=1ms service=11325ms status=200 bytes=540
2015-03-20T13:40:26.585221+00:00 app[web.1]: Completed 200 OK in 4954ms (Views: 0.3ms | ActiveRecord: 20.3ms)

【问题讨论】:

【参考方案1】:

问题不在于您的 Rails 应用程序 - 它通过 301 重定向消息正确响应到不使用 https 的连接。

是否遵循 301 重定向取决于客户端。我的猜测是您的网络浏览器遵循重定向,但 cURL 没有。

也许这会有所帮助:Is there a way to follow redirects with command line cURL

【讨论】:

以上是关于Rails 应用程序 HTTP 到 HTTPS 重定向不适用于公开的 API的主要内容,如果未能解决你的问题,请参考以下文章

Rails 使用 https 重定向

HTTPS 重定向 Elastic Beanstalk 环境 Puma Rails 5

Heroku 应用程序自动重定向到 HTTPS

如何在不丢失 Google 索引的情况下正确地将网站从 http 重定向到 https

如何在 Rails 中重定向到 404?

在 Rails 4 上登录后,ngrok、pow 和 devise 会导致重定向到本地 URL