Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you make rails 3 work as a backend for mobile apps with support for session_id's in the request?

I am trying to build a rails 3 back-end for a mobile application. However, I am new to creating rails 3 apps.

Users will need to have a session on the server, but I have no support for normal cookies, so I would need to send a session_id along with every request.

What kind of authentication system should I use in rails 3, is there a gem?

I have read that in rails 2 it was possible to set the session_id from the URL, but that this function is stripped from rails 3 due to security concerns. Is this even true? If there is a way to do this, I am very interested, despite the possible security holes.

like image 227
Mosselman Avatar asked Apr 07 '11 19:04

Mosselman


People also ask

How does a mobile app work with backend system?

It is a piece of software that runs on machines called servers. Backend development for mobile applications empowers the main working of the application. It incorporates things like servers, databases, middleware, and so on and can be accessed through the internet via an application programming interface (API).

Can Ruby on Rails be used for mobile apps?

Ruby on Rails gives a competitive edge for mobile solutions for Android and iOS. In RoR, Ruby is the language of coding or the programming language and Rails is a framework that provides default structures for a database, a web service, and web pages and used for creating the web or mobile application.


2 Answers

Usually I'd use HTTP Digest authentication to solve this problem. Most of the Rails authentication plugins (such as Authlogic, probably Devise) will support HTTP Basic or Digest authentication though a plugin. In this way, you don't have to worry about expired cookies and the like.

You can also pass an api_key parameter instead of a session id.

In many cases I've used an api key as the HTTP Basic username. This gives clean URLs and session-less authentication.

The security problem you're probably referring to is Cross-Site Request Forgery. It is indeed a real problem. Its why you hide actions with side effects (create, update, destroy) behind forms with a CSRF token. Otherwise a malicious link can perform unintended actions to a site that you're already authenticated to without needing to know your credentials.

As long as your API key isn't easily discoverable by anyone in an automated fashion, the risk should be minimal.

like image 97
adamlamar Avatar answered Nov 29 '22 17:11

adamlamar


Update

A small update: Devise no longer has authentication_token as its implementation was deemed too insecure. A good alternative is Brian Auton's suggestion.

The summary of his method is that he generates an authentication_key AND authentication_secret in a separate model. You then authenticate by sending both your key and secret, if a match is found you are temporarily signed in as a user.

In your application controller this looks like so:

class ApplicationController < ActionController::Base
  before_filter :authenticate_from_token

  protected

  def authenticate_from_token
    if current_token.try :authenticatable
      sign_in token.authenticatable, store: false
    end
  end

  def current_token
    AuthenticationToken.find_authenticated({
      secret: (params[:secret] || request.headers[:secret]),
      secret_id: (params[:secret_id] || request.headers[:secret_id]),
    })
  end
end

The authenticatable of the token in this case is a User model, or any other thing that has been made authenticatable (the tokens are polymorphic). As you can see it can easily be made to work with Devise.

I like this method a lot and have implemented it in a recent API. Do read up on it on his website.

Old answer

Outdated answer, kept for reference to older versions of Devise: Devise has a 'authentication_token' column which I can use for authenticating a user. I could have a login API method which I will send a username + password too, then get the token back and store that locally to sign all my other calls with. It basically is a cookie system, but one that is directly supported by Devise.

On top of this I could re-generate the token on either every call or on every 'session'.

like image 33
Mosselman Avatar answered Nov 29 '22 15:11

Mosselman