Quickstart

A quick dive into getting started with Lore

Step 4: Redirect to Login

In this step we're going to redirect the user to the /login route if they aren't authenticated.

You can view the finished code for this step by checking out the authentication.4 branch of the completed project.

Local Storage & User Tokens

While our API does not currently require the user be authenticated, we will be replacing it with a real API later that will. That API is going to require users to be authenticated before they can create, update or delete tweets.

In order to authenticate the user, we will need to send an authentication token in the header of every API request, and the token we'll be sending will be provided to us by Auth0 after the user logs in.

Also, in order to prevent asking the user to log in every time they refresh the page (or navigate away from the site), we'll be storing this token in the browser's localStorage, and only redirect the user to the login page if they have no token.

Auth Utility

If you look inside src/utils you'll find a file called auth.js. This file contains some helper methods for saving and retrieving a user token from localStorage.

For example, when the application loads, we're going to check if a userToken exists in localStorage by calling auth.hasToken(), and once we have a token, we'll be able to save it to localStorage by calling auth.saveToken(token).

You can read more about this file here.

Redirect the User

Open routes.js and find the route that renders the Master component. It should look like this:

// routes.js
<Route component={UserIsAuthenticated(Master)}>
  ...
</Route>

The UserIsAuthenticated() function that wraps Master is a higher order component that can block access to the application if the user isn't authenticated. Currently this component isn't doing anything because the blocking behavior is turned off. Let's turn it on.

To do that, open src/decorators/UserIsAuthenticated.js, which looks like this:

// src/decorators/UserIsAuthenticated.js
import PropTypes from 'prop-types';
import { AuthenticationGenerator } from 'lore-auth';

export default AuthenticationGenerator({

  propTypes: {
    router: PropTypes.object.isRequired
  },

  redirect() {
    const { router } = this.props;
    router.push('/login');
  },

  isAuthenticated() {
    return true;
  }

});

When this component gets mounted, the isAuthenticated() method is called. If it returns true, whatever component this wraps is rendered. If it returns false, the redirect() method is called, and you can send the user somewhere else.

You can read more about this file here.

Since this function currently returns true, the application never redirects the user to /login. To get the behavior we want, import src/utils/auth.js and update the isAuthenticated() method to look like this:

// src/decorators/UserIsAuthenticated.js
import auth from '../utils/auth';
...
  isAuthenticated() {
    return auth.hasToken();
  }
...

If you now try to navigate to the root route at https://localhost:3000, the application will redirect you to /login.

Visual Check-in

If everything went well, your application should now look like this.

Code Changes

Below is a list of files modified during this step.

src/decorators/UserIsAuthenticated.js

import PropTypes from 'prop-types';
import { AuthenticationGenerator } from 'lore-auth';
import auth from '../utils/auth';

export default AuthenticationGenerator({

  propTypes: {
    router: PropTypes.object.isRequired
  },

  redirect() {
    const { router } = this.props;
    router.push('/login');
  },

  isAuthenticated() {
    return auth.hasToken();
  }

});

Next Steps

Next we're going to add a callback route and save the token.