Rails ActionController会忽略请求标头

时间:2018-07-12 11:22:56

标签: ruby-on-rails cors ruby-on-rails-5 rack rack-cors

我有一个简单的控制器方法,该方法通过ActionController的#headers方法记录标头:

class ThingsController < ActionController::Base
  def show
    Rails.logger.info headers
    render json: {response: 'success'}
  end
end

但是,当我通过带有标题的curl调用此控制器方法时,不会记录它们:

curl "http://localhost:3000/things/1” \
  -H "access-token XXX" \
  -H "token-type Bearer" \
  -H "client YYY" \
  -H "expiry 1234" \
  -H "uid test@test" \

相反,将记录以下标头:

{"X-Frame-Options"=>"SAMEORIGIN", "X-XSS-Protection"=>"1; mode=block", "X-Content-Type-Options"=>"nosniff"}

我认为应该归咎于我的Rails 5应用程序的CORS策略,因此我安装了rack-cors gem并在下面的初始化程序中对其进行了配置。不幸的是,它并没有改变结果。

Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins '*'
    resource '*',
      headers: :any,
      methods: %i(get post put patch delete options head)
  end
end

1 个答案:

答案 0 :(得分:2)

我认为这与CORS无关。

在Rails 5.2中,将ActionController实例方法#headers委派给response对象。 https://github.com/rails/rails/blob/v5.2.0/actionpack/lib/action_controller/metal.rb#L150

delegate :headers, :status=, :location=, :content_type=,
         :status, :location, :content_type, to: "@_response"

要访问请求标头,可以通过request对象进行。 http://api.rubyonrails.org/classes/ActionDispatch/Request.html#method-i-headers

此外,您需要更改cURL语法以从值中分隔键。

curl "http://localhost:3000/things/1” \
  -H "access-token: XXX" \
  -H "token-type: Bearer" \
  -H "client: YYY" \
  -H "expiry: 1234" \
  -H "uid: test@test" \

对于每个Rack spec(和RFC 3875),客户端发送的标头都以HTTP_为前缀,并且所有出现的-都被_替换。

要记录通过cURL指定的标题,请执行以下操作:

class ThingsController < ActionController::Base
  def show
    Rails.logger.info {
      request.headers.env.slice(
        "HTTP_ACCESS_TOKEN",
        "HTTP_TOKEN_TYPE",
        "HTTP_CLIENT",
        "HTTP_EXPIRY",
        "HTTP_UID"
      )
    }
    render json: {response: 'success'}
  end
end