Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RoR: testing an action that uses http token authentication

Tags:

I'm trying to test a controller that's using an http token authentication in the before filter. My problem is that it works ok wheh I use curl to pass the token, but in my tests it always fails (I'm using rspec btw). Tried a simple test to see if the token was being passed at all, but it seems like it's not doing so. Am I missing anything to get the test to actually pass the token to the controller?

Here's my before filter:

    def restrict_access
      authenticate_or_request_with_http_token do |token, options|
        api_key = ApiKey.find_by_access_token(token)
        @user = api_key.user unless api_key.nil?
        @token = token #set just for the sake of testing
        !api_key.nil?
      end 
    end

And here is my test:

    it "passes the token" do
      get :new, nil,
        :authorization => ActionController::HttpAuthentication::Token.encode_credentials("test_access1")

      assigns(:token).should be "test_access1"
    end
like image 855
JoseMarmolejos Avatar asked Aug 20 '12 15:08

JoseMarmolejos


People also ask

Which is the example of authentication token?

These are three common types of authentication tokens: Connected: Keys, discs, drives, and other physical items plug into the system for access. If you've ever used a USB device or smartcard to log into a system, you've used a connected token.

What is token based authentication explain with suitable example?

What Is Token-based Authentication? Token-based authentication is a protocol that generates encrypted security tokens. It enables users to verify their identity to websites, which then generates a unique encrypted authentication token.

How do authentication tokens work?

Token based authentication works by ensuring that each request to a server is accompanied by a signed token which the server verifies for authenticity and only then responds to the request.


1 Answers

I'm assuming ApiKey is an ActiveRecord model, correct? curl command runs against development database, and tests go against test db. I can't see anything that sets up ApiKey in your snippets. Unless you have it somewhere else, try adding something along these lines:

it "passes the token" do
  # use factory or just create record with AR:
  ApiKey.create!(:access_token => 'test_access1', ... rest of required attributes ...)

  # this part remains unchanged
  get :new, nil,
    :authorization => ActionController::HttpAuthentication::Token.encode_credentials("test_access1")

  assigns(:token).should be "test_access1"
end

You can later move it to before :each block or support module.

UPDATE:

After seeing your comment I had to look deeper. Here's another guess. This form of get

get '/path', nil, :authorization => 'string'

should work only in integration tests. And for controller tests auth preparation should look like this:

it "passes the token" do
  request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Token.encode_credentials("test_access1")
  get :new
  assigns(:token).should be "test_access1"
end

Reasons behind this come from method signatures for respective test modules:

# for action_controller/test_case.rb
def get(action, parameters = nil, session = nil, flash = nil)

# for action_dispatch/testing/integration.rb
def get(path, parameters = nil, headers = nil)
like image 81
Serge Balyuk Avatar answered Jan 03 '23 04:01

Serge Balyuk