What is the correct way to capture an authorization header from a controller request object?

I have two RSpec tests, the controller specification and the request specification, where I make a GET request for the index action of the same controller. In both specifications, I send an authorization header containing an Oauth2 token carrier.

The problem I am facing is that, depending on the type of specification, the header is stored in another property of the request object. In the case of a request specification, it is available in request.env["Authorization"] , and in the case of a controller specification it is available in request.session["Authorization"] .

Why is “authorization” stored in different places for different types of specifications? Somewhere I can find it for both specifications?

This bearer_token method is in the class of the parent controller, where I grab the token from the header:

Works with env in the request specification:

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

Works with session in controller specifications:

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

Here is my request specification:

 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 

Here is my controller specification

 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 
+8
ruby-on-rails ruby-on-rails-3 rspec
source share
1 answer

I assumed that the API would be the same for the get method between the request specification and the controller. In the controller specification, the third argument is a hash of session variables, not header variables. You can customize the headers directly on the @request object as follows:

 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 

Then the correct way to get the authorization header:

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

All Articles