Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the proper way to grab Authorization header from controller request object?

I have two RSpec tests, a controller spec and a request spec, where I am making a GET request to the index action of the same controller. In both specs I am sending an Authorization header that contains an Oauth2 bearer token.

The problem I'm having is that depending on the type of spec, the header is stored on a different property of the request object. In the case of the request spec, it is available at request.env["Authorization"] and in the case of the controller spec, it is available at request.session["Authorization"].

Why is "Authorization" stored in different places for different types of specs? Is there somewhere I can find it for both specs?

This bearer_token method is in the parent controller class where I'm grabbing the token from the header:

Works with env in the request specs:

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

Works with session in the controller specs:

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

Here is my request spec:

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 spec

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
like image 403
Peter Brown Avatar asked Aug 08 '14 14:08

Peter Brown


People also ask

Which headers do we use to provide Authorization?

The HTTP Authorization request header can be used to provide credentials that authenticate a user agent with a server, allowing access to a protected resource. The Authorization header is usually, but not always, sent after the user agent first attempts to request a protected resource without credentials.

Where is Authorization header stored?

These can be stored in the browser local storage or session storage.

How do I send Authorization header in request Axios?

Here's how you can set the Authorization header, which is typically used to send access tokens to a server. // Send a GET request with the authorization header set to // the string 'my secret token' const res = await axios. get('https://httpbin.org/get', { headers: { authorization: 'my secret token' } });


1 Answers

I assumed that the API would be the same for the get method between a request and controller spec. In the controller spec, the third argument is a hash of sessions variables, not header variables. You can set the headers directly on the @request object like so:

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 is using:

def bearer_token
  pattern = /^Bearer /
  header  = request.env["Authorization"] # <= env
  header.gsub(pattern, '') if header && header.match(pattern)
end
like image 110
Peter Brown Avatar answered Sep 18 '22 08:09

Peter Brown