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
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? 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.
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.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With