Javascript – Securing the Node.js app’s REST API

backbone.jsjavascriptnode.jsrestrestful-authentication

I could do with some help on my REST API. I'm writing a Node.js app which is using Express, MongoDB and has Backbone.js on the client side. I've spent the last two days trying to work out all of this and not having much luck. I've already checked out:

I want to keep my backend and frontend as separate as possible so I thought about using a carefully designed REST API would be good. My thinking is that if I ever get round to developing an iPhone app (or something else like that), it could use the API to access data.

BUT, I want this to be secure. A user has logged into my web app and I want to ensure my API is secure. I read about OAuth, OAuth 2.0, OpenID, Hmac, hashes etc… I want to avoid using external logging in (Facebook/Twitter/etc) I want the registering and logging in to be on my app/server.

…but I'm still confused here. Maybe it's late at night or my brain is just fried, but I could really do with some steps on what to do here. What are the steps for me to create a secure API?

Any help, any information, any examples, steps or anything would be great. Please help!

Best Answer

In order of increasing security / complexity:

Basic HTTP Auth

Many API libraries will let you build this in (Piston in Django for example) or you can let your webserver handle it. Both Nginx and Apache can use server directives to secure a site with a simple b64encoded password. It's not the most secure thing in the world but it is at least a username and password!

If you're using Nginx you can add a section to your host config like so:

auth_basic "Restricted";
auth_basic_user_file /path/to/htpasswd;

(Put it in your location / block)

Docs: http://wiki.nginx.org/HttpAuthBasicModule

You'll need to get the python script to generate that password and put the output into a file: http://trac.edgewall.org/browser/trunk/contrib/htpasswd.py?format=txt

The location of the file doesn't matter too much as long as Nginx has access to it.

HTTPS

Secure the connection from your server to the app, this is the most basic and will prevent man in the middle attacks.

You can do this with Nginx, the docs for it are very comprehensive: http://wiki.nginx.org/HttpSslModule

A self-signed certificate for this would be fine (and free!).

API Keys

These could be in any format you like but they give you the benefit of revoking access should you need to. Possibly not the perfect solution for you if you're developing both ends of the connection. They tend to be used when you have third parties using the API, eg Github.

OAuth

OAuth 2.0 is the one to go with here. While I don't know the underlying workings of the spec it's the defacto standard for most authentication now (Twitter, Facebook, Google, etc.) and there are a ton of libraries and docs to help you get those implemented. That being said, it's usually used to authenticate a user by asking a third party service for the authentication.

Given that you doing the development both ends it would probably be enough to put your API behind Basic HTTP Auth and serve it over HTTPS, especially if you don't want to waste time messing around with OAuth.