Menu

Ionic JWT auth with facebook using nodejs. Part 1

02 July 2016

Recently on a work project I had to create JWT authentication with multiple OAuth providers and integrate it with Ionic app. While there are a lot of tutorials and guides online, I found some of them incomplete or addressing some other use cases.

In this 2 part blog post we are going to build a simple ionic app with express server to make the authentication and signing the JWT tokens.

Why JWT tokens?

They are self-contained, which means that each token equipped with all the information needed for the authorization process including the expiration time and the issuer of the token. You can also attach additional payload data to the token, which can be decoded to a plain JS object on the client and back on your server. The payload can include user information such as his db ID, name, role and other useful information.

JWT tokens are multi-platform, we can use them on our ionic app, web-app and for api endpoints on the server. Since JWT transferred over JSON you can use them with multiple languages.

They are light-weight and can be attached to http headers easily.

I would suggest searching the web about JWT, there are a lot of great resources describing the details about them. We won’t go any further describing JWT since we just want to see them in action with our Ionic app.

Ok, so JWT are awesome! Let’s start coding.

Nodejs server

We will start with a simple express app that our client will be able to contact. In this project I will use ES6 syntax so grab the latest node version preferred 6.2.2.

So our app.js file contains all necessary configuration and boilerplate. Note that we require a few files to our main file. Let's start examine those.

.env file

This file is containing all server configurations, API KEYS, and other sensitive data. It is usually a good practice not to upload this file to the git repository and place the .env in a .gitignore file. You can allways use .env.example as a blueprint file for your teammates.

AuthModule.js

This file will contain all of our authentication logic, we don't want it to be coupled to our routes, so will extract all of it to a different module.

In this module we will export 2 methods, facebookAuthentication and createOrRetrieveUser.

facebookAuthentication

Will be responsible for converting our Authorization code acquired from our ionic app. We will send a GET request to the facebook api to exchange our auth code to an accessToken which will allow as later to get the users profile information. We will want to normalize facebook profile object to user object similiar to our UserSchema, so later we will be able use different providers, and reuse other parts of our authorization process.

In order to communicate with facebook api you will need to obtain a FACEBOOK_SECRET key. To do so you will have to create an app on facebook developers panel.

Go grab your app id and secret key from settings page and put them inside your .env file. We will use the app id later with our ionic app.

createOrRetrieveUser

Will simply search the users collection for a user matching profile id based on the authorization type. in our case will search for the facebook key on our Schema. Later we can add additional providers as well.

We will make use of expressjs middlewares to use with our authentication routes. Express middlewares are simply functions that inserted inside the request pipeline to add functionality or process the request before responding to the client.

We will create our auth route with multiple middlewares, each of them will be responsible for its own part. So later when we will introduce more authentication methods we will be able to reuse most of our code.

Note that the request is passed inside of all the controller methods in the exact order:

We exchange our authorization token with an access token, and then fetch the user profile in a normalized object.

With the user object passed along with the auth provider from the previous middleware we will search for the user inside the DB. If found, return the user to the next step, if not create the user and then return him to next step.

Generate the token including user info payload.

Finally we will send the token back to the user as json

Protected routes

Later when we want to check if the user is authenticated in order to access specific endpoint we can write simple middleware: