Passwordless Authentication in React Native Using Facebook Account Kit (Part 2)
By: Juan Pablo Garcia
Tags: Node, React, Authentication, React Native, JavaScript

In this article we will create the services that we described on the introductory Part 1, to be ultimately used on Part 3 of this series.

Introduction

We will create a simple API with two services:

/auth: this will allow us to verify the code from Facebook Account Kitobtained from the application and identify or create the user on our database for future login attempts. This service will also return a JWT(JSON Web Token) to identify the user on the next requests that require security. /me: based on the user credentials provided in the JWT, this endpoint will check with the database and return the required user data.

Project Setup

For this example we will use NodeJS’ framework Hapijs, but you can use other languages/frameworks that you feel comfortable with.

We will begin by creating a new project and installing the following dependencies:

yarn init

yarn add hapi hapi-auth-jwt2 jsonwebtoken lowdb node-fetch qs

yarn add -D nodemon

Then, open the package.json file and add the following line on the scripts section. This will allow us to refresh the server on the fly, as changes are introduced:

"scripts": {

...

"start": "nodemon ./index.js -e js",

...

}

Finally, we create an index.js file and start coding.

You can find the complete code for this example on this Github Repository.

Configuring the server

On this step we’ll be adding the necessary libraries and code a simple route to verify that everything is working properly.

It’s worth noting two important aspects of the code we include below:

The creation and initialization of a database to store users as they register. For simplicity, in this example we chose lowdb, which is a simple database that stores data on disk. The configuration of a Hapijs strategy using hapi-auth-jwt2 that will allow us to intercept requests with a JWT on the Authorization header, verify that said JWT is valid, include the data as part of the request and access them easily by calling request.credentials from any route that we secure, as we will see further on.

The constant JWT_SECRET is included as a part of this example to keep this as simple as posible, but on a real scenario we strongly suggest you obtain it from an environment variable. Moreover, we suggest you use a random auto-generated key (for example using a tool such as openssl).

In order to verify this, we run the command yarn start and from a browser we request the page http://localhost:3000, which should return the text OK.

Programming the authentication service /auth

First of all, we create the following environment variables and constants.

If you wish to use the Facebook application that we created on Part 1 of this series of articles, you will have to replace the values.

The constant FACEBOOK_APP_SECRET is included as a part of this example to keep this as simple as posible, but on a real scenario we suggest you obtain it from an environment variable.

We then replace the route we created above on this post with something that makes a little more sense:

Change the method GET to POST and configure the strategy using { auth: false } as to avoid the interception of the request in search of a JWT. Create the function getFacebookToken which will be in charge of verifying the code provided by the user in the application, along with the id and secret of our Facebook application. Asides, we will use the access_tokento check for more information on the Facebook user. In this case, the phone number. Create the function getFacebookMe to check the user data using the access_token. Last, we code the method handleAuth with the logic for the route in question. We save the user on the database if they didn’t already exist and generate and return the signed JWT.

Programming the secure service /me

For the previous step to make sense, we will now create a route that will require the user to be registered. In this case, the route will return the user’s profile from the database:

We add the route and, in the configuration, we include the parameter { auth: 'jwt' } so that the strategy we previously defined will return the credentials from the client on the request.auth variable. We create the method handleMe with the necessary logic to search a user by their identifier in the database and return the full profile.

And…you’re all set! All that’s left is to integrate the application with the services as described on Part 3.

Passwordless Authentication Using Facebook Account Kit