Writing an API with Clearance
Recently, I needed to write an API to work with an iPhone application. I used Clearance for authentication. Unfortunately, it doesn’t support HTTP Basic Authentication out of the box, which made it difficult to use in an API.
I found this issue with
a patch that worked. However, the
Thoughtbot guys said that Rack::Auth::Basic
should be used instead. No
examples were provided.
I tried for a few days to get things to work with Rack and ended up using that patch.
Today I decided to take another look at this. I found a cached slideshow on Google that had the info I needed to make an API using a Sinatra app as a Rails Metal.
This is basically how I got HTTP Basic Auth working with Clearance:
# Put this in app/metals/api.rb
require 'sinatra/base'
class Api < Sinatra::Base
before do
content_type :json
authenticate if api_request?
end
helpers do
def api_request?
request.path_info.match %r{/api/}i
end
def authenticate
unless authenticated?
response['WWW-Authenticate'] = %(Basic realm="My API")
throw(:halt, [401, "Unauthorized\n"])
end
end
def authenticated?
auth = Rack::Auth::Basic::Request.new(request.env)
auth.provided? && auth.basic? &&
auth.credentials && @current_user = User.authenticate(*auth.credentials)
end
def current_user
@current_user
end
end
get '/api/account.json' do
current_user.to_json
end
end
Hope it helps someone else having this problem.