Authentication for Single Page Applications and API’s in the SANE Stack pt 1

Sane stack logo

Per popular request, let’s now talk about the big bogeyman that scares all the new devs – authentication. Authenticating old fashioned websites used to be pretty simple and usually used domain cookies and server sessions, but nowadays that is not a very viable strategy because you usually need multiple clients accessing your API – web, mobile, 3rd party etc. Additionally, nowadays for scalability sake, API’s are preferred to be state-less – the server doesn’t preserve user state which means there can be no server session. This is why the dominant strategy has become OAuth2 and is used for Google’s and other industry leaders’ public facing API’s.

Disclaimer

Authentication and authorization are big and sensitive topics which have been the subject of many books. This is a small and limited example and should be treated as such. It is by no means a full blown solution for enterprises with sensitive materials. There are many extensions and alterations that can be done to make this example better, but I could only fit so much in the scope of one article. The most obvious extension is that in a real world scenario the tokens need to be saved in the database and tracked and validated that way. I will expand on this in a future tutorial.

What is OAuth2?

It is the successor of OAuth of course. But really what is it? It was pretty mysterious to me, until I got linked to the actual draft by the OAuth Working Group  where it is defined as:

 The OAuth 2.0 authorization framework enables a third-party
   application to obtain limited access to an HTTP service, either on
   behalf of a resource owner by orchestrating an approval interaction
   between the resource owner and the HTTP service, or by allowing the
   third-party application to obtain access on its own behalf.

The 3rd party wording is a bit confusing. Why are we using a strategy for 3rd party auth? Since most engineers choose to not have 1 monolithic project, but break things up into multiple services and clients, your clients  essentially end up being considered 3rd party as far as your API’s are concerned and different API’s can talk to each other, also being treated like 3rd party.

Visually in a scenario which allows refresh tokens, this looks like this:

oauth2-refreshtoken

The tokens which you see on the chart are JSON Web Tokens (JWT). The client requests authorization from the authorization server, if credentials are correct, it is granted an access token and a refresh token. Further requests from the client to the API must include this access token in the header. If the token is present and valid, the resource server responds with the desired resource, otherwise it returns an error. When the access token is set to expire, the client sends the refresh token and if it is valid, the server responds with a new access token.

* Keep in mind that there are certain complexities which are omitted from this chart, for example user roles and security level for resources – should some be only read by the owner, should all users be able to read them, in either case, only the owner and an admin should be able to edit and delete a resource. This is implied by the naming ‘authorization server’, but it’s not explicitly explained. We’ll discuss taking care of that in a future tutorial.

The implementation

Now that the theory is somewhat clear, let’s see how we can implement this with code in the SANE stack. As always we use the “How To SANE” project as our demo.

3rd Party Modules

All this is pretty complex and prone to errors especially for developers new to it. Abiding by all the protocol clauses can be quite tedious, but fear not, there are very helpful modules to the rescue. I used 3 in particular which were designed according to the protocols for OAuth2 and JWT. Namely ‘jsonwebtoken’ and ‘express-jwt’by Auth0 for the server and Ember Simple Auth by Simpl Labs for the client. These modules are open-source, free and take care of the heavy lifting to achieve this authentication strategy. Here is what each of them does:

jsonwebtoken takes care of issuing and verifying json web tokens according to the protocol of the work group.

express-jwt is a middleware for express which extracts the token from the header and validates it, if it is found to be valid, it attaches the logged  in  user as the req.user object, so further middleware know which user is logged in.

ember-simple-auth is the client implementation and it does quite a bit for you on the client side – it maintains a client session in local storage which contains the token, when it expires and what user is logged in. Using that it creates a session object in browser memory which is available to ember from anywhere and can be used to alter the app’s behavior based on whether a user is logged in or not. It also provides an ‘protected route’ mixin which allows you to bar visitors who aren’t logged in from seeing protected areas of your app. Ember-simple-auth also has a renewal scheduling mechanism, it reads the expires_in value the server sends it when obtaining a token and attempts a renewal when the time comes so the user is not booted when the token expires.

You can find out how to install and use these modules in their according github repos, the node ones are as simple as a npm install and a require, while ember-simple-auth also takes a generate command and then certain mixins have to be extended and you are good to go.

Our own code

With all these powerful and convenient modules, our code ends up quite minimal. The bulk of it ends up being in our AuthController in sails where we have 2 endpoints, login and logout. The login point is the interesting one and the logic in it behaves like the chart above:

If a request is type password and has user credentials we look for that user and password combo in the database and if they are valid, we issue an access and renewal token and respond to the client with them. They are automatically stored in local storage by Ember Simple Auth and from then on our client behaves accordingly – like that user is logged in. Further requests sent by Ember contain a Authorization header which starts with “Bearer “ and then contains the encrypted token.

If a request is type renew, the logic takes the renew token and compares it to the access token it came with and if they are found to contain the same user and expiration dates, new tokens are issued with an expiration date further in time.

We configure Ember Simple Auth to use this endpoint in the Ember environment config – the keys having to do with simple auth. It is used for both issuing and renewing tokens automatically.

Next we have to configure sails to police  the end points we’d like to protect. We make a  hasToken policy which screens for incoming tokens in server/api/policies. It uses express-jwt and if it finds a valid token on the request it attaches the user to the request. If not, it returns a 400 error to the client. To specify which routes should be using this policy we go to server/config/policies and specify that all routes (*)  should be run through the hasToken policy, except the Users Controller and the Auth Controller. This way to get anything out of the API you need a token, but you can make a new user or login without having a token and thus obtain one.

This is it for now. In a future tutorial we will explore authorization – how to save tokens in the database and validate them that way and how we can implement user roles and authorization levels for resources for each role.

6 thoughts on “Authentication for Single Page Applications and API’s in the SANE Stack pt 1

  1. Artem

    February 15, 2015 at 10:36pm

    Good tutorial, thanks! I was searching for emberjs-nodejs with REST apis tutorials for a few days and yours is the first one that I manage to make working (could be more about my skills though).

    One question about security in the example: shouldn’t you cover exactly signup/login routes with SSL? Well, it may be a good idea to run whole API behind HTTPS at least in production, but if signup/login aren’t SSL’ed then username and password are going to be transferred as plain text, aren’t they?

  2. Artem

    February 15, 2015 at 10:37pm

    Good tutorial, thanks! I was searching for emberjs-nodejs with REST apis tutorials for a few days and yours is the first one that I manage to make working (could be more about my skills though).

    One question about security in the example: shouldn’t you cover exactly signup/login routes with SSL? Well, it may be a good idea to run whole API behind HTTPS at least in production, but if signup/login aren’t SSL’ed then username and password are going to be transferred as plain text, aren’t they?

    P.S.
    Resubmitting this comment with the notification subscription.

    • mgenev@gmail.com

      February 17, 2015 at 5:41pm

      Yes, HTTPS would be absolutely necessary in production

  3. Artem

    February 17, 2015 at 10:43pm

    And then I tried to actually follow the tutorial to have a boilerplate for my own project and.. figured this is not really a tutorial, but just some hints for the final project :)

    Oh well, I guess I need to start with the full thing then and try cutting out images stuff out to keep only user things and one page with something belonging to the user.

    • mgenev@gmail.com

      February 18, 2015 at 2:26am

      the project is definitely ahead in features of the blog tutorials. But what is in the tutorials is indeed demonstrated in the project.

  4. Branson

    March 28, 2015 at 8:18am

    hey i was going through your how to sane app ,the one on github and i really want to know you made the relationships work on the server and if there was anything special since i cant find a thing on the net concerning sailsjs and relations and yet if theres anything special to be considered…awesome work guyz!!

Comments are closed.