【问题标题】:What is the proper way to grab Authorization header from controller request object?从控制器请求对象中获取授权标头的正确方法是什么?
【发布时间】:2014-08-08 14:41:08
【问题描述】:

我有两个 RSpec 测试,一个控制器规范和一个请求规范,我正在向同一个控制器的索引操作发出 GET 请求。在这两个规范中,我都发送了一个包含 Oauth2 不记名令牌的授权标头。

我遇到的问题是,根据规范的类型,标头存储在请求对象的不同属性中。在请求规范的情况下,它在request.env["Authorization"] 可用,在控制器规范的情况下,它在request.session["Authorization"] 可用。

为什么不同规格的“授权”存储在不同的地方?有什么地方可以找到两种规格的吗?

这个bearer_token 方法位于父控制器类中,我从标头中获取令牌:

在请求规范中使用env

def bearer_token
  pattern = /^Bearer /
  header  = request.env["Authorization"] # <= env
  header.gsub(pattern, '') if header && header.match(pattern)
end

适用于控制器规格中的session

def bearer_token
  pattern = /^Bearer /
  header  = request.session["Authorization"] # <= session
  header.gsub(pattern, '') if header && header.match(pattern)
end

这是我的请求规范:

describe '' do
  let(:user) { Fabricate(:user) }

  describe 'accessing content with valid token' do
    let(:token) { OauthToken.create(user: user) }
    let(:auth_headers) { {
      'Authorization' => "Bearer #{token.access_token}",
      'HTTPS' => 'on'
    } }
    before { get api_v2_cats_path, {}, auth_headers }
    specify { response.status.should == 200 }
  end
end

这是我的控制器规格

describe Api::V2::CatsController do
  let(:user) { Fabricate(:user) }

  describe ".index" do
    let(:token) { OauthToken.create(user: user) }
    let(:auth_headers) { {
      'Authorization' => "Bearer #{token.access_token}",
      'HTTPS' => 'on'
    } }

    it "should be valid" do
      get :index, { format: :json, page_size: 1 }, auth_headers
      @json = JSON.parse(response.body)
      @json.should_not be_nil
    end
  end
end

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 rspec


    【解决方案1】:

    我假设请求和控制器规范之间的 get 方法的 API 相同。在控制器规范中,第三个参数是会话变量的散列,而不是标头变量。您可以直接在@request 对象上设置标题,如下所示:

    describe Api::V2::CatsController do
      let(:user) { Fabricate(:user) }
    
      describe ".index" do
        let(:token) { OauthToken.create(user: user) }
        let(:auth_headers) { {
          'Authorization' => "Bearer #{token.access_token}",
          'HTTPS' => 'on'
        } }
    
        before do
          @request.env.merge!(auth_headers)
        end
    
        it "should be valid" do
          get :index, { format: :json, page_size: 1 }
          @json = JSON.parse(response.body)
          @json.should_not be_nil
        end
      end
    end
    

    那么获取授权头的正确方法是使用:

    def bearer_token
      pattern = /^Bearer /
      header  = request.env["Authorization"] # <= env
      header.gsub(pattern, '') if header && header.match(pattern)
    end
    

    【讨论】:

    • 只是一个改进,你可以从header.gsub(pattern, '') if header &amp;&amp; header.match(pattern) chage 到header.gsub(pattern, '') if header&amp;.match(pattern)
    【解决方案2】:

    我找到了这个。

    https://github.com/rails/rails/commit/cf9d6a95e805bdddfa9c6b541631d51b3165bf23#diff-10b31f2069dfc4810229c8d60c3a4cda

    在您的控制器中,您可以执行类似的操作来获取标头值。

    
    def index
    
      header_value = request.authorization
    
    end
    

    【讨论】:

    • 这很简单,而且效果很好。谢谢。这对我帮助很大。
    猜你喜欢
    • 2013-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-28
    • 1970-01-01
    • 2021-10-23
    • 2017-08-10
    相关资源
    最近更新 更多