Implementing API for a Rails app - ruby-on-rails

I am building an API for my rails app i am trying to reuse same controllers for both API and app logic. The requests without authenticating a user is fine but how to implement if some actions need an authentication. I am using authlogic, to edit people need some specific permissions which i am checking in the before_filter. If i implement an API using http basic authentication how do i differentiate ?

I think there are two parts to the answer. Firstly you need to set up http basic auth with authlogic. The details for doing that are contained in this SO answer: Rails: Basic Authentication with Authlogic
Then you need to differentiate between API calls and normal browser calls in your controller. Assuming your API is XML or JSON, you can do that with something like this:
class ThingsController < ApplicationController
before_filter :authorize
def authorize
if params[:format] == 'json' || params[:format] == 'xml'
require_http_auth_user # http basic auth for API access
else
require_user # normal authlogic authentication
end
end
end

It may be worthwhile separating into two separate controllers and including the common functionality via a mixin. That way you can auth the controllers separately.

Related

Use Devise Session to Authenticate Doorkeeper API for Rails/Ember app

I'm developing a Rails app along with a corresponding API and contemplating introducing Ember for some particularly dynamic front end components. I'm using Devise for authentication and Doorkeeper to secure API endpoints and manage OAuth tokens.
I don't want to replace the login piece with Ember so the Ember app will likely be initialized once the user logs in on the primary "logged in index" page. I'd like the Ember app to use the public API rather than rendering JSON from my rails-centric controllers, partly for simplicity and partly to force me to keep the API up to date.
Since the user is already logged in, I don't think it makes sense to do the OAuth dance and get a token. Instead I'd like the API to allow requests from clients that have been logged in by Devise (presence of session / cookie). Effectively, you should be able to visit /api/v1/resources.json in a browser once logged in to the app and receive a JSON response. Currently its a 401 Unauthorized.
Does this seem like a reasonable approach? If so, does anyone have experience doing this?
For anyone interested in this in the future, the answer was pretty straightforward:
module Api
module V0
class ApiController < ActionController::Base
before_action :doorkeeper_authorize!, unless: :user_signed_in?
end
end
end
The key part being unless: :user_signed_in?, which is provided by Devise

Allow authenticated Devise user to access Doorkeeper protected controller actions

My API uses OAuth2 with Doorkeeper and authentication at the UI level is with Devise.
My app is made up of plain ol' slim files but I need to add an autocomplete search input which sends the query to one of the API endpoints via AJAX.
The user is authenticated via devise session and available as current_user but since the API endpoint is protected with before_action :doorkeeper_authorize! I get a 401.
Is there anyway to "bypass" the doorkeeper_authorize! is the user is already authenticated via Devise?
One option is to copy the action out of the API controller and add in my "normal" UI centric controller which is just protected with Devise but that's just ugly.
Here's a solution I used that worked for me.
before_filter :doorkeeper_authorize!, :unless => :logged_in?
I'm not using devise so I'm not familiar with the methods used for checking authentication, but I have a logged_in? method on my application_controller that will return true if the user is authenticated locally (via cookie). This short-circuits any of the Oauth checking.

How to implement API authentication for Rails app with Authlogic

I have a Rails app with an iOS mobile client.
So far, I've had the iPhone client send HTTP requests to the normal URLs. I want to replace this with a proper API. I'm on Rails 3, and I'm using Authlogic for authentication.
I have watched the railscasts on versioned apis and securing APIs. But since I'm already using authlogic for authentication, I think reimplementing token creation would be unnecessary?
I created the API just as Ryan Bates suggests in this episode with a controller under app/controllers/api/v1/. I have corresponding views with RABL in views/api/v1.
My controller is
module Api
module V1
class RecordsController < ApplicationController
respond_to :json
def index
status = RecordStatus.where("name = ?", "processed").first
#records = current_user.records.where("record_status_id = ?", status.id)
end
def show
#record = Record.find(params[:id])
end
end
end
end
Basically, I've read a lot on the different options to implement (including a bunch of answers on SO) and I'm just really stumped as to what's the best way for me to implement authentication, securely. Should I go to oauth? Can I do it with authlogic? Which option would make it easy to use from the iOS side? Which option is easiest to implement?
Any guidance would be helpful.
Perhaps you could use the single access token stuff that's in authlogic already?
http://rubydoc.info/gems/authlogic/Authlogic/Session/Params

Rails 3 gdata site wide youtube client

i want to uses youtube's api within rails.
I need a client which is able to access youtubes api application wide.
therefore i wrote the following application controller
require 'gdata'
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :auth
def auth
#client = GData::Client::YouTube.new
#client.clientlogin('usermail', 'password')
#client
end
end
i am able to use the client now in my controllers which extend ApplicationController.
thats working fine.
but its pretty slow.
is there a way to do the authentication once and using it application wide instead of suing the before_filter which is getting called every single time before i call a method?
best,
philip
This is a web page. Webpages are state-less. Thus you cannot preserve any state. Thus you cannot preserve your login across requests. Thus you have to auth every request.
An alternative would be to only run the before filter on certain controller actions. Right now it runs on every action, which my be not necessary.
Try:
before_filter :auth, :only=> my_action_name
(P.S. That might be the wrong syntax -- I'm confused 'cause rails changes so much -- just look it up)

Ruby ways to authenticate using headers?

I am designing an API system in Ruby-on-Rails, and I want to be able to log queries and authenticate users.
However, I do not have a traditional login system, I want to use an APIkey and a signature that users can submit in the HTTP headers in the request. (Similar to how Amazon's services work)
Instead of requesting /users/12345/photos/create I want to be able to request /photos/create and submit a header that says X-APIKey: 12345 and then validate the request with a signature.
Are there any gems that can be adapted to do that? Or better yet, any gems that do this without adaptation?
Or do you feel that it would be wiser to just have them send the API key in each request using the POST/GET vars?
You probably use an authentication library already. It probably has a way to override the way it checks for authentication. Most likely, the method is named authenticated?. Refer to the documentation for the library you are using, though.
I would not have looked for an existing gem, but implemented it myself; doing so shouldn't be too hard. Here's an example boilerplate implementation:
class ApplicationController < ActionController::Base
def authenticated?
current_user.is_a?(User)
end
def current_user
user_from_session || user_from_api_key
end
def user_from_session
# ... use session[:user] or whatever.
end
def user_from_api_key
User.find_by_api_key(request.headers["X-APIKey"])
end
end
That's as specific as I can get, since you don't say anything about your current authentication setup.

Resources