Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a secure Rails REST Api for my app?

So I am making an app for Android that needs a web backend. The website is being build in Ruby on Rails. It has a client facing side (pretty HTML pages) but I also want it to be able to serve information to my Android app via JSON. However, I don't want the whole world to be able to get this JSON as it contains some possibly dangerous information. How do I lock down the JSON-formatted pages and still make them accessible from the Android app?

For the record, I am using Rails 3.1 has_secure_password for on-site user authentication, and I'd like to have some routes that are open for HTML requests but locked for JSON (for example, the /users url should be accessible as HTML but as JSON it should only be accessible from my app with some security method).

Is there any way to do this, or does the API have to be a separate app (that would be hugely inconvenient with the DB setup, etc.)?

CLARIFICATION: Basically what I want to do is create a secure token-based JSON API from my Rails app,and I don't want to use Devise or something that will force me to change how i am already storing my user/pass information.

like image 493
Sam Stern Avatar asked Nov 04 '22 21:11

Sam Stern


1 Answers

Depending on which version of rails you are using, part of the work is already done with the respond_to method, which allows you to serve both JSON and HTML for the same url. Now, to lock down JSON access, you could define a method that checks app access, and call it whenever serving up the JSON response

def with_access_check()
  if allowed # Or any verification you want.
    yield
  else
    # Raise a 403 maybe?
  end
end

# Then in every method that needs a check:
respond_to :json { with_access_check { render :json => @stuff } }

Finally, unless you're serving very different data on the json and html views (which is weird if you're using the same url for both) consider that nothing can stop an attacker/malicious user from extracting that very same data from your HTML.

like image 62
Christophe Biocca Avatar answered Nov 08 '22 04:11

Christophe Biocca