How to secure your HTTP API endpoints using Facebook as OAuth provider

Standard

Heads up!

The blog has moved!
If you are interested in reading new posts, the new URL to bookmark is http://blog.valeriogheri.com/

 

This post is the natural follow-up of my post “How to build and test your Rest API with Node.js, Express and Mocha”.
Here I’ll show you a possible solution to the problem of authenticating your API users via Facebook, accessing some user’s basic info like name, profile pic and email and using the given Facebook access token to secure all your API endpoints.

Solution:

This is quite a common scenario nowadays yet I couldn’t find many useful source of information. So I went ahead and asked a question on StackOverflow (http://stackoverflow.com/questions/15602667/possible-approach-to-secure-a-rest-api-endpoints-using-facebook-oauth). The solution described below is heavily inspired by the answer given by user Tommy Crush, so thanks Tommy!

The logical steps are:

  1. Login via Facebook on your app (either mobile or web) and obtain the Facebook Access Token

  2. Pass the Facebook Access Token to the server (over SSL for the android app, and for the web app just have it redirect to an API endpoint after FB login)

  3. Check the given Facebook Access Token to make sure it is valid by making a graph call to the /me endpoint. Parse the response to get user id and email and cross-reference this with existing users to see if it’s a new or old one.

  4. Now create a random token, store it and associate it to the user id and give the API token back to the requesting app. If you need Facebook for anything other than login, store it too in your DB and associate it with the new api_access_token and your user_id.

  5. For every call hereafter, send the api_access_token to authenticate it. If you need the fb_access_token for getting more info, say retrieveing the list of your user’s friends, you can do so by retrieving it from the DB.

Code:

The code shown below  is taken from my current project ShopWithMe available on GitHub  (https://github.com/vgheri/ShopWithMe) and uses a Node.js + Express.js + MongoDB with mongoose technology stack.

I’ll go into details starting of points 3 and 5. Points 1, 2 and 4 should not be a issue.

Step 3: Verify facebook access token

To verify if the given token is valid we need to make a call to the /me endpoint of the Facebook Graph API located at the URL https://graph.facebook.com/me?access_token=$fb_access_token
The result, if token is valid, is a JSON blob containing the user’s information accessible using this token.
This blob should, at its minimum, look like the following:

{
  "id": "xxxxxx",
  "name": "XXX XXX",
  "first_name": "XXX",
  "last_name": "XXX",
  "link": "https://www.facebook.com/XXX",
  "username": "xxxxxx",
  "gender": "xxx",
  "email": "xxx",
  "timezone": 2,
  "locale": "en_US",
  "verified": true,
  "updated_time": "2013-08-14T09:16:58+0000"
}

Otherwise should we have an error response, that’s the JSON blob we’ll get back:

{
  "error": {
    "message": "XXX",
    "type": "OAuthException",
    "code": XXX,
    "error_subcode": XXX
   }
}

As a hint, if you want to try this on the browser, just go to https://developers.facebook.com/tools/explorer/?method=GET&path=me being logged in with Facebook on your browser. Obtain the Facebook Access Token and then point your browser to the URL https://graph.facebook.com/me?access_token=$fb_access_token , where $fb_access_token is the token you just obtained. You should see a JSON object containing your info if all went well (why shouldn’t it? J)

Point 5:
Point 5 is about securing your API endpoints, making sure that only authenticated users can access the data and authorize the request.
Express.js has a nice and easy way to allow a developer to play with the request pipeline, all that is needed is adding a function in the route declaration.
Let’s see how:
In the file where I defined my routes, I just need to update the routes I want to secure, simply modifying them like this:

BEFORE:
app.get(‘/api/profiles/:userId’, handlers.account.getAccount);

AFTER:
app.get(‘/api/profiles/:userId’, authorisationPolicy, handlers.account.getAccount);

As it should be clear, I just added a function called authorisationPolicy to the route declaration that inside the pipeline is processed ahead of the handlers.account.getAccount function .
Let’s see into detail this authorisationPolicy function:

This function executes its authentication policy and if everything is fine, it calls the Express.js next() function, which takes care of executing the next stage in the pipeline.
If otherwise the request should not be authorized, we can send back an error response.

Conclusion

In conclusion what we have seen is a simple yet effective way to integrate Facebook login into your HTTP API and to secure your endpoints.
The key here is to use the Facebook token to identify your users and then to issue your own API tokens to secure your endpoints.

Javascript promises and why jQuery implementation is broken

Standard

Introduction to Javascript promises

Callbacks: a classic approach to async

Callbacks are Javascript classic approach to collaborative asynchronous programming.
A callback is a function object that is passed to another function as a parameter and that  later on must be invoked under some circumstances: for example when an asynchronous function successfully completes a task, it invokes the callback function to give back control to the function that was previously executing, signaling that the task has completed.
Callbacks are easy to use, but they make the code less readable and messier, especially if you have few of them one after another using anonymous functions:

Small example

function invokingFunction() {
    // some stuff
    asyncFunction(function(data) { // the first callback function
                   anotherAsyncFunction(function() { // the second callback function
                          //more stuff
                   });
             });
}

This pattern can lead to what is known as the “pyramid of doom”, especially when using jQuery’s mouse event handlers combined with async operations like $.get or $.post.

Javascript promises: the specification

To fix this and other problems (as we’ll see) with callbacks style of code, a specification has been proposed and it is known under the name CommonJS Promises/A. Let’s see what it says:

A promise represents the eventual value returned from the single completion of an operation. A promise may be in one of the three states, unfulfilled, fulfilled, and failed. The promise may only move from unfulfilled to fulfilled, or unfulfilled to failed. Once a promise is fulfilled or failed, the promise’s value MUST not be changed, just as a values in JavaScript, primitives and object identities, can not change (although objects themselves may always be mutable even if their identity isn’t). The immutable characteristic of promises are important for avoiding side-effects from listeners that can create unanticipated changes in behavior and allows promises to be passed to other functions without affecting the caller, in same way that primitives can be passed to functions without any concern that the caller’s variable will be modified by the callee.
[…]
A promise is defined as an object that has a function as the value for the property ‘then’:
then(fulfilledHandler, errorHandler, progressHandler)
Adds a fulfilledHandler, errorHandler, and progressHandler to be called for completion of a promise. The fulfilledHandler is called when the promise is fulfilled. The errorHandler is called when a promise fails. The progressHandler is called for progress events. All arguments are optional and non-function values are ignored. The progressHandler is not only an optional argument, but progress events are purely optional. Promise implementors are not required to ever call a progressHandler (the progressHandler may be ignored), this parameter exists so that implementors may call it if they have progress events to report.
This function should return a new promise that is fulfilled when the given fulfilledHandler or errorHandler callback is finished. This allows promise operations to be chained together. The value returned from the callback handler is the fulfillment value for the returned promise. If the callback throws an error, the returned promise will be moved to failed state.

It’s very easy to find blog articles and tutorials online, especially around jQuery Deferred object, and almost all of them show how to do callback aggregation using the “then” function to attach callbacks to a promise, whether for success or for errors (or even to signal that an operation has made some progress). When the promise transitions state, the callbacks will be called, that’s as simple as that.
After reading a lot, I thought I knew enough about promises, but then I stumbled upon this page (https://gist.github.com/3889970) by Domenic Denicola, titled “You’re Missing the Point of Promises”, and after reading it I really had the feeling I was missing it entirely!

What promises are really about

As the previously linked page states, Javascript promises are not just about aggregating callbacks, but actually they are mostly about having a few of the biggest benefits of synchronous functions in async code!
Namely

  1. function composition: chainable async invocations
  2. error bubbling: for example if at some point of the async chain of invocation an exception is produced, then the exception bypasses all further invocations until a catch clause can handle it (otherwise we have an uncaught exception that breaks our web app)

To quote Domenic:

The point of promises is to give us back functional composition and error bubbling in the async world. They do this by saying that your functions should return a promise, which can do one of two things:

  • Become fulfilled by a value
  • Become rejected with an exception

And, if you have a correctly implemented then function that follows Promises/A, then fulfillment and rejection will compose just like their synchronous counterparts, with fulfillments flowing up a compositional chain, but being interrupted at any time by a rejection that is only handled by someone who declares they are ready to handle it.

That is, promises have their foundation in this “then” function, if this is broken than the whole mechanism is broken. And that is exactly what is happening with jQuery’s implementation, let’s see why with the help of an explicative (I hope!) code example.

Why jQuery promises are broken

The problem with jQuery’s implementation (up until version 1.9) is that it doesn’t respect the second part of the specification, “This function should return a new promise…”, that is “then” doesn’t return a new promise object when executing one of the handlers (either the fullfillment, the rejection or the progress handler).

This means we cannot do function composition as we don’t have a “then” function to chain to, and we won’t have error bubbling due to a broken chain, the two most important points about this spec.
Finally, what we have is just callback aggregation.

JsFiddle examples

The following fiddles show a simple chain of async functions.
I’m simulating the case where the original promise is fulfilled, the fulfillment handler is invoked, gets the data and then throws an exception in response to it. The exception should be handled by the first rejection handler down the chain.

The first fiddle  is not working as expected: the rejection handler is never invoked and the error bubbles up to the app level, breaking it. Below I show the console reporting the uncaught error:

Uncaught errors

Uncaught errors

Next fiddle  behaves as expected, with the rejection handler correctly invoked. The way to quickly “fix” the broken implementation is to wrap the handler with a new Deferred object that will return a fulfilled/rejected promise, that can be later used for chaining, for example. Below we see the  console showing no uncaught errors.

No errors

No errors

Alternatives

As we have seen, until at least version 1.9.0, jQuery can’t do pomises properly out of the box, but there are several alternatives libraries on the market such as Q, rsvp.js and others, that adhere completely to the specification.

Conclusion

Promises are the present and the future of Javascript asynchronous operations, they provide an elegant and readable code and more importantly they allow function composition and error bubbling, making async more similar to sync programming style, thus making the life of a developer a little bit easier!
I said that Promises are the future of Javascript async programming because Harmony, the next version of Javascript, will allow for great stuff combining promises with Generators. To see a sneak peek preview on how powerful these two concepts can be if used together, point your browsers to http://www.taskjs.org !

Credits

Again, credits to Domenic Denicola for writing this post  and to all the ones who commented and posted examples that helped me understand, notably user jdiamond!