Authenticate React App With Stormpath - Part One
Tags: react, beginners, javascript
Published: 2019-10-17 08:07:23

React is a Javascript library that helps break down complex UI into simple and reusable components that can be composed together. I will show you how to build a react app from scratch, using the Stormpath React SDK to add sign up, login and view profile features. 

Let's get started!

You'll first need to create a <a href="https://api.stormpath.com"> Stormpath</a> account and application, which you can do here: https://api.stormpath.com/register

Stages we are going to cover:-
<ul style="padding: 0">
<li>Install the React + Express.js Application Stack</li>
<li>Set up the React + Express.js Project</li>
<li>Master Page</li>
<li>Index Page</li>
<li>Login Page</li>
<li>Registration Page</li>
<li>Profile Page</li>
<li>Home Route</li>
<li>Logout</li>
<li>User State in Components</li>
<li>Import Components</li>
<li>Run The project</li>
<li>Wrapping Up</li>
</ul>

### Install the React + Express.js Application Stack

In this tutorial, we will use <a href="https://babeljs.io/docs/en/learn"> ES6</a> and <a href="https://babeljs.io/docs/en/babel-plugin-transform-react-jsx/">JSX</a> to write as little code as possible as well as <a href="https://github.com/stormpath/stormpath-sdk-react">Stormpath</a> React SDK for user features.

Here's a break down of what we will use:-
<ul>
<li>React - Allows us to compose simple yet powerful UIs.</li>
<li>ReactRouter - Organizes the URL navigation in our React application.</li>
<li>ES6 - The next version of JavaScript. Allows us to write real JavaScript classes.</li>
<li>JSX - Allows us to place HTML in JavaScript without concatenating strings.</li>
<li>Stormpath - Allows us to store and authenticate users without having to create our own backend for it.</li>
<li>Stormpath React SDK - Integrates Stormpath into our React application with very little effort.</li>
<li>Express - Allows us to serve our HTML and JavaScript files.</li>Express Stormpath - Allows us to serve Stormpath's API through Express.</li>
<li>Webpack - Allows us to pack all of our JavaScript files into one bundle.</li>
<li>Babel - Allows us to transpile our ES6 and JSX into ES5.</li>
<li>Bootstrap - Because we want things to be pretty.</li>
</ul>

### Set up the React + Express.js Project

Create a directory where your project will sit

```console
   $ mkdir my-react-app
   $ cd my-react-app
   $ npm init --yes
```

Install Express and the Stormpath module for Express:

```console
  $ npm install --save express express-stormpath body-paser
```
   
Next, we will create a server to host our application. Create a new file ``server.js`` and paste the code below:

```javascript
const express = require('express');
const stormpath = require('express-stormpath');

const app = express();

app.use(stormpath.init(app, {
   web: {
      produces: ['application/json']
   }
}));

app.on('stormpath.ready', function(){
   app.listen(3000, 'localhost', function(err){
      if(err){
         return console.error(err)
      }
      console.log('Listening at http://localhost:3000')
   });
});
```
Next, we can go ahead and hook this up to our Stormpath Application by creating a new file ``stormpath.yml`` with the following code in it. Of course, you have to replace the values with your own.

```yaml
   client:
      apikey:
         id: YOUR_API_KEY_ID
         secret: YOUR_API_KEY_SECRET
   application:
      href: https://api.stormpath.com/v1/applications/XXXX <-- YOUR APP HREF
```

Try the server by running ``$ node server.js``. If everything is set up correctly, you'll see:-

```console
Listening at http://localhost:3000
```
Great, you can give yourself a thumbs up for that. You've earned yourself a badge for successfully configuring your server to communicate with Stormpath and expose a REST API for your React.

<b> Configure Webpack </b>

Moving on swiftly, terminate the server so that we can install the Webpack package. As we mentioned earlier, Webpack is going to package all of our client-side scripts. We will need this organization soon!

```console
$ npm install --save webpack
$ npm install --save-dev webpack-dev-middleware
```

We will configure Webpack by creating a new file named ``webpack.config.js``by inserting the code below:


```javascript
const path = require('path');
const path = require('webpack');

module.exports = {
   entry: [
      './src/app'
],
devtool: 'eval-source-map',
output: {
   path: __dirname,
   filename: 'app.js',
   publicPath: '/js/'
},
module: {
   loaders: []
 }
};
```
So let's dissect this code:-

What this code does, is that it will look in our ``/src/`` directory (don't worry, we will create that) and package all of the scripts and their dependencies under that directory as one module. Then use the file ``/src/app.js`` and its exports as the export of that module. Then finally when it has generated that module package, it will serve that through ``Express`` under the ``/js/app.js`` endpoint.

In order for Express to serve Webpack files, we have to add a few lines on top of the scripts in ``server.js`` file:

```javascript
   const webpack = require('webpack');
   const config = require('./webpack.config');
```
 
Then immediately after the line ``const app = express();`` add:

```javascript
const compiler = webpack(config);

app.use(require('webpack-dev-middleware')(compiler, {
   noInfo: true,
   publicPath: config.output.publicPath
}));
```

Again, this will allow Webpack to intercept requests and serve our packaged ``/js/app.js`` file.

<b> Configuring Babel </b>

Since we will be using ES6 and JSX, we need to transpile these files into ES5 (for backward compatibility with non-modern browsers). Babel does this. It takes ES6/JSX files as input, and convert them to ES5.

So, as usual, we are going to install Babel package

```console
   $ npm install --save babel-core babel-runtime babel-loader babel-plugin-react-transform \
  babel-preset-es2015 babel-preset-react babel-preset-stage-0
```

Next, just as we did with Webpack, we are going to configure babel by creating a new file ``.babelrc`` and adding this code:-

```json
{
   "presets": ["stage-0", "es2015", "react"]
}
```

Finally, we need to edit ``webpack.config.js`` in order to allow Babel to work with our Webpack. We will add an entry to the ``module.loaders`` array:

```javascript
   module: {
      loaders: [{
         test: /<.js$/,
         loaders: ['babel'],
         include: path.join(__dirname, 'src')
}]
}
```

<b> Index.html and Bootstrap </a>

Before deep-diving into React and getting ourselves wet, we'll set up the entry page for our app. This page will instruct the browser on what it must load before we initialize React and our application.

Start by creating a new directory ``build``, inside it, create a file ``index.html``. Our server will serve all our static files from this folder.

```console
   $ mkdir build
   $ cd build
   $ touch index.html
```

Within ``index.html``, insert this:

```html
<!doctype html>
<!--[if lt IE 7]><html class="no-js lt-ie9 lt-ie8 lt-ie7"><![endif]-->
<!--[if IE 7]><html class="no-js lt-ie9 lt-ie8"><![endif]-->
<!--[if IE 8]><html class="no-js lt-ie9"><![endif]-->
<!--[if gt IE 8]><!-->
<html class="no-js"><!--<![endif]-->
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <base href="/">
    <title></title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width">
    <link rel="stylesheet" href="/css/bootstrap.min.css" />
  </head>
  <body>
    <div id="app-container"></div>
    <script src="/js/app.js"></script>
  </body>
</html>
```

If you are using Visual Studio Code as your editor, you can install the ``HTML-5 Boilerplate`` extension to easily generate the HTML script.

Moving on, in the ``build`` folder, create a new directory ``css`` and download bootstrap files to it. 

```console
$ mkdir css
$ cd css
$ curl -O https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css
$ cd ../.. # return to /my-react-app
```

In order for our browser to access these files, we need to configure them so that they are served through Express. Open up ``server.js`` and at the top of the file add:


```javascript
const path = require('path');
```

Under the line ``app.use(stormpath.init(app, ...));`` add:

```javascript
app.get('/css/bootstrap.min.css', function(req, res) {
   res.sendFile(path.join(__dirname, 'build/css/bootstrap.min.css'));
})

app.get('*', function(req,res) {
   res.sendFile(path.join(__dirname, 'build/index.html'));
});
```

### A Little Bit on How React Works

We now have a skeleton for our app done, next we will focus on building our React app. But before that, let's try to understand React.

<b>Components</b>

In React, everything is built upon components. Think of a component as an element on the DOM e.g. Navigation Bar, Header, Login Form ... etc. A component is basically something that renders a DOM node. A simple React component looks like this:-

```javascript
class FirstComponent extends React.Component {
   render(){
      return <div>First Component</div>
   }
 }
```

To render this component to the page, you need to import react and then call it:

```javascript
ReactDOM.render(
   <FirstComponent />,
   document.getElementById('first-component')
);
```

And React would render the component to that element.

Of course, there are more things to a React component, such as <a href="https://thinkster.io/tutorials/understanding-react-state"> state</a> , componentWllMount, componentWillUnmount etc. To give you a glimpse of this, let's create a simple React Component counter that starts counting immediately when added to the DOM and stops when removed.


```javascript
class Counter extends React.Component {
   state = {
      current: 0
   }

   constructor(){
      super();
      this.intervalId = null;
   }

   updateCounter(){
      this.setState({current: this.state.current + 1})
   }

   componentWillMount(){
      this.setState({ counter: this.props.from || 0 });
      this.intervalId = 
      setInterval(this.updateCounter.bind(this), 1000);
   }
   componentWillUnmount(){
      clearInterval(this.intervalId);
   }
   render(){
      return <span>{ this.state.current }</span>
   }
}
```

So now let's try to understand this. The methods ``componentWillMount()`` and ``componentWillUnmount()`` are <a href="https://reactjs.org/docs/glossary.html#lifecycle-methods"> life-cycle</a> methods that will be executed at various points of a component's life-cycle (in this case, mount and unmount). The methods are usually used for setting up and tearing down a component and is necessary to use because React will error if you try to set the state of a component when it hasn't been mounted yet.

The member ``this.props`` is a collection of all the properties (inputs) passed to a component. Properties of a component can be set like this:

```html
   <Counter from="50" />
   <Counter from={ myVariable } />
```

<b> JSX Variables </b>

Variables can easily be interpolated into your JSX DOM using { nameOfVariable }, e.g. like this:

```javascript
   render(){
      let myVariable = 123;
      return <span>{ myVariable }</span>
   }
```

<b> JSX and Reserved JavaScript Identifiers </b>

Since JSX is JavaScript, there are some caveats that you need to know when working with React. i.e when setting properties of a React DOM component you cannot use neither ``for`` nor ``class`` since those are considered reserved JavaScript identifiers. To get around this problem, React has come with ``htmlFor`` and ``className`` that you should use instead.

To illustrate the issue, this won't work:

```html
   <label for="my-input" class="my-label">My Input</label>
```

But this will:

```html
   <label htmlFor="my-input" className="my-label">My Input</label>
```

<b>Virtual DOM</b>

Instead of working directly against the DOM, in React all components are kept in their own <a href="https://reactjs.org/docs/faq-internals.html#what-is-the-virtual-dom"> virtual DOM</a>. You can think of the virtual DOM as a DOM implementation in JavaScript (because it actually is). This virtual DOM is then mapped to a real DOM element. So when you render your React component, React will look at the DOM output from the component, compare it to its representation in the virtual DOM, and then generate a patch for the real DOM.

What this means is that you never have to think of manually manipulating DOM elements again. All you have to do is tell React how you want your component to look like, and it will take care of transforming the DOM the ways necessary (with minimal effort).

<b>Installing React Dependencies</b>


Now that we are acquainted with React, we'll kick things off by installing some React dependencies:

```console
   $ npm install --save react react-dom react-router react-stormpath react-document-title history
```

Before we start coding, we need a place to put our React files, so create a new directory named ``src``, and then use that as your working directory.

```console
   $ mkdir src
   $ cd src
```

Now, let's start with the entry point of our app. This will be the place where we will set up our React application and its routing. So create a new file named ``app.js`` and enter this code:

```javascript
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, IndexRoute, Route, browserHistory } from 'react-router';

ReactDOM.render(
  <Router history={browserHistory}>
  </Router>,
  document.getElementById('app-container')
);
```

So now we have a foundation for our application. Let's go ahead and import the Stormpath SDK and some things we'll need in it. At the top of your app.js file, add the import statement:

```javascript
   import ReactStormpath, { Router, HomeRoute, LoginRoute, AuthenticatedRoute } from 'react-stormpath';
```

As you can see in ``app.js`` there's now two conflicting ``Router`` imports. Since ``ReactStormpath.Router`` extends from ``ReactRouter.Router`` we won't be needing that anymore. So go ahead and remove the ``Router`` import from ``react-router``. Important: Leave the other ReactRouter imports, we'll be needing those later.

Now, we'll initialize the Stormpath SDK. Add the following line right above ``ReactDOM.render()``.

```javascript
   ReactStormpath.init()
```

That was easy! We're now ready to start building our pages on Part Two of this tutorial.