Reputation: 1054
I haven't had the time to go through .6 and .7 as well as .8 in depth to make sure that I wasn't missing something, but today I decided to update my application, which is mostly an API with some front end work.
I updated the application to rails 4.1.8 and I got a lot of errors in my specs, in fact anything where the api had to be authenticated it blew up.
My controllers that use an api have a method called restrict_api_access
which is done via
def restrict_api_access
authenticate_or_request_with_http_token do |token, options|
@api_key = ApiKey.find_by(api_key: token)
end unless current_user
end
Now you can log into the app and manage things, in that case we still use the same API that you would access say via a terminal or out side app. so the unless current_user
basically looks like like:
def current_user
if (@api_key)
@current_user = User.find_by!(id: @api_key.xaaron_users_id)
else
super
end
end
Ans then the super
of this current user basically states - are you logged in or not.
So one of the tests that are failing is set up like such:
context "Create new tag" do before(:each) do @tag = FactoryGirl.build(:tag, blog_id: @blog.id) set_auth_header(@user) end
it "should create a tag for a post" do
post :create, :blog_id => @blog.id, tag: {name: @tag.name, description: 'asdasddsa'}
json = JSON.parse(response.body)
expect(json['tag']['name']).to eql @tag.name
end
end
@user
is set up else where. But I can assure you that a user is being passed in and is created.
The other interesting method here is set_auth_header(@user)
this method looks like:
# Create a random api key
def create_api_key(user)
ApiKey.create!(:xaaron_users_id => user.id, :api_key => SecureRandom.hex(16))
end
# Set authentication headers for the API use
def set_auth_header(user)
key = create_api_key(user)
request.env['HTTP_AUTHORIZATION'] = "Token #{key.api_key}"
end
You can see we create an API key with the user, we then set the request environment variable to have that api key.
So before 4.1.8 (I was on 4.1.5) this worked fine, all my tests would pass life was grand. Now, with this particular test, I get:
1) Api::V1::TagsController Create new tag should create a tag for a post
Failure/Error: json = JSON.parse(response.body)
JSON::ParserError:
757: unexpected token at 'HTTP Token: Access denied.
'
# ./spec/controllers/api/v1/tags_controller_spec.rb:112:in `block (3 levels) in <top (required)>'
Essentially I am denied access. I have traced this through to the restrict_api_access
to the line: authenticate_or_request_with_http_token
which holds, as a value: HTTP Token: Access denied.
Is there something that changed in 4.1.8 that would be causing all my api that requires authentication to break?
Upvotes: 0
Views: 139
Reputation: 171
You're computing your authorization header manually here, which might be wrong:
request.env['HTTP_AUTHORIZATION'] = "Token #{key.api_key}"
There's an ActionController method that does this for you:
request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Token.encode_credentials(key.api_key)
Try that instead.
Upvotes: 1