3

I'm starting to build a really small API and I need to authenticate some endpoints, not all of them. I want to be able to select which endpoint to force authentication with an authenticate! method to be called in the body of the 'route'.

For example:

resource :groups do
    desc 'List all groups.'
    get do
      authenticate!
      { groups: "list of groups v1"}
    end
end

I have this working. I used a helper where I manually get the base64 encoded data from the header using: request.env["HTTP_AUTHORIZATION"]. I decode that data and check against the database if the user and secret belongs to a registered user. This is working fine, but I want to use Grape's helper to avoid all the base64 decoding etc etc:

http_basic do |username, password|
end

My idea is inside that method always return true, assign username and password to @username and @password and have a helper that grabs those variables and check against the db. All that works fine, the problem is that for routes that doesn't require authentication as the 'Authorization' header is empty the popup asking for password appears, and I want to avoid that. Is there a way to use the helper to do what I want to do??

BTW: I'm using grape mounted on rails-api

Thanks!

Andres
  • 11,439
  • 12
  • 48
  • 87

2 Answers2

1

Ok, if I got it right you don't want the username / password box to appear, but instead decide in your code if you actually need the authentication information.

Grape itself uses the default Rack::Auth::Basic class. If you create a customized version of this class you should be able to make your assertions at the beginning of the call method and even pass any other variables to your http_basic block.

You can then add your Authentication strategy to Grape via:

# Add authorization strategy to grape and replace default http_basic
Grape::Middleware::Auth::Strategies.add(:http_basic, Your::Namespace::CustomizedBasicAuth, ->(options) { [options[:realm]] })

This way there is also no need to save the credentials in @username and @password. You could just include or reference the logic inside this authentication strategy.

Nevertheless I somehow would still prefer to split up the API into two parts as Eric already mentioned.

croeck
  • 696
  • 1
  • 11
  • 19
0

You can break up your Grape::API into multiple modules. Group the modules that need http_basic auth together. Group the modules that don't need http_basic auth separately

Eric Himmelreich
  • 407
  • 4
  • 13
  • THanks for the comment. But my problem is more oriented on using the http_basic method to decode the authorization header instead of doing it manually as I'm doing it. – Andres May 11 '15 at 14:23