我希望有人能为我解决一些问题。我正在使用 Rails 2.3.5,我可以像这样在 Controller 操作中访问请求 header :
def index
if request.headers['...'] == '...'
...
end
end
或类似的东西。 request.headers 是 ActionController::Http::Headers 的一个实例这似乎是一个哈希。因此,我希望 header 以我发送的名称为关键字。但是,如果我发送请求,带有 Authorization header ,像这样:
curl -H 'Authorization: OAuth realm="MyRealm",...' http://app/path
操作中的以下代码返回 false:
if request.headers.include?('Authorization') ...
而以下回应了我在 header 中发送的值:
render :text => request.headers['Authorization']
有趣的是,以下检查返回 true:
if request.headers.include?('HTTP_AUTHORIZATION') ...
类似地,以下回应了我在 header 中发送的值:
render :text => request.headers['HTTP_AUTHORIZATION']
似乎发生了一些我不知道的魔法。我完全不明白为什么检查 key “授权”失败,但呈现 request.headers['Authorization'] 的值却成功。我也对“HTTP_AUTHORIZATION”的来源感到困惑,因为它不是我随请求发送的 header 的名称。任何人都知道到底发生了什么?
最佳答案
你是对的 - ActionController::Request
的 headers
方法返回一个 ActionController::Http::Headers
的实例,它是继承自哈希。如果我们破解源代码,我们会看到:
class Headers < ::Hash
extend ActiveSupport::Memoizable
def initialize(*args)
if args.size == 1 && args[0].is_a?(Hash)
super()
update(args[0])
else
super
end
end
def [](header_name)
if include?(header_name)
super
else
super(env_name(header_name))
end
end
private
# Converts a HTTP header name to an environment variable name.
def env_name(header_name)
"HTTP_#{header_name.upcase.gsub(/-/, '_')}"
end
memoize :env_name
end
因此,当通过 []
访问哈希时,会进行第二次检查以查看是否来自 env_name
的值(它只是将键大写并添加 HTTP_
) 存在。
这就是为什么您无法从 request.headers.include?('Authorization')
中获取真实值的原因 -- include?
未在子类中被覆盖检查 header 的正常版本和大写版本。我想您可以效仿并像这样自己实现它:
module ActionController
module Http
class Headers < ::Hash
def include?(header_name)
self[header_name].present?
end
end
end
end
将其放入 lib/extensions/action_controller.rb
或其他内容,如有必要,在 environment.rb
中要求它,您应该可以开始了。不过,我建议只修改您的 Controller 代码以使用 []
和 present?
进行检查:)
原因,标题被大写并以 HTTP_
为前缀,我相信,源于 Rails 的 HTTP 中间件 Rack。它可能这样做是为了保持对大小写的公正,另外在 HTTP_
之前加上以避免与进来的其他非 header 环境内容发生冲突。
所以,是的,有点神奇,但在浏览了源代码后并不难理解,我一直推荐 :) Rails 有一些非常好的源代码,我多年来从中学到了很多东西。
关于ruby-on-rails - 使用 key HTTP_AUTHORIZATION 而不是授权访问 Ruby on Rails 中的授权 header ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2311883/