Adding Authentication to a React App with Auth0
Tags: react, auth0, javascript, authentication
Published: 2020-12-02 18:32:14

##Why Authenticate with Auth0?

It is no surprise that authentication is important for a number of reasons, the main one being that it enables the end-user to keep their content secure, this could be in regards to large corporations securing their computer system, networks , databases or just a single user that wants their account and information safe and secure. Effective web authentication is simple to use and  allows the users to log in and out with ease. Auth0 is a provider of authentication that is simple to implement and provides a great user experience.

## What We'll Build

In this article, we are going to create a simple authentication system with a React application covering how the authentication process works and put theory into practice.

First we need a React application to authenticate, so if you haven't already open up your code editor and create a new folder called react-auth0.

Open up your terminal and in the file directory you just created run, 

`npx create-react-app react-auth`

For simplicity let's clean the React App up a bit. Navigate to the public folder and delete everything apart from index.html.
With src, delete app.test.js, index.css, logo.svg, serviceWorker.js and setupTests.js.
Within your public.html delete everything until it looks like this:
![index](https://dev-to-uploads.s3.amazonaws.com/i/yjag1w7j4k6wc76a4qfl.png)

Likewise for index.js, make sure it looks the same as below.
![index2](https://dev-to-uploads.s3.amazonaws.com/i/jan28o68r9fs6j3e3w19.png)

Then in app.js,
![app](https://dev-to-uploads.s3.amazonaws.com/i/q4vn050rss4x1fe0jv5w.png)

And finally, navigate to your app.css file and delete everything within it and save the changes.

Now you have a React application skeleton ready to authenticate with Auth0!  

##Creating an Auth0 Account

Auth0 is free to sign up to and can be done so by following this [link](https://auth0.com/).
Once you have signed up, navigate to Applications in the lefthand panel and create an application, selecting Single Page Web Applications for application type.

Once created choose your technology, in this example we will be using React.

##Configure Auth0 Application

You will need to configure some of the settings within your Auth0 application before adding it to your React app.
First to configure is the Callback URL - This is the URL in your application that Auth0 redirects to after the user has been authenticated.

Within Application Settings, navigate to 'Allowed Callback URLs and set this to:
 
`http://localhost:3000/`

If this field is not set, users will not be able to log into the application.

Next to configure is the Logout URL - This is the URL that Auth0 returns the users to after they log out. If this is not set, users will not be able to logout.
Within Application Settings, navigate to 'Allowed Logout URLs' and also set this to:

`http://localhost:3000/`

Last to configure is Web Origins - This concerns refreshing the authentication tokens and if not configured will logout the user when they either refresh the page or revisit the page without logging out.

Within Application Settings, navigate to 'Allowed Web Origins' and set this to:

`http://localhost:3000/`

That is it for configuring your auth0 application, now lets head back to our React app and get Auth0 implemented!

First install Auth0 within the app. Within the terminal, *make sure you are in the right directory before doing this:*

`npm install @auth0/auth0-react`

Once installed we are going to need some data from our Auth0 Application Settings, the Domain and Client ID, now in order to keep this sensitive information secure we need to create a .env file, pass this information into the file and add .env to .gitignore.
So within your React app, create a file and call it .env. Within this file add:

`REACT_APP_AUTH0_DOMAIN =`
`REACT_APP_AUTH0_CLIENT_ID =`

On the other-side of the = operator add *your* Domain and Client ID found in Application Settings on Auth0 website.

Then at the bottom of your .gitignore file add the .env file you just created like so:
![ignore](https://dev-to-uploads.s3.amazonaws.com/i/0crhg2ipq31hq5mkq389.png)
 
Now we have our environment variables set up we can start implementing the auth application within React.

Within index.js, we need to import Auth0Provider and the environment variables we just created:
![AuthProvider](https://dev-to-uploads.s3.amazonaws.com/i/kyammkidu54qcodtm5w7.png)

Now we can use auth provider which will ultimately wrap the app in the ReactDom.render. The auth provider component uses react context which will allow us to access all of its properties from within App!

Within Auth0Provider we can now specify domain and clientId so that the components we create shortly will have access to them. At this point we will also want to pass in redirectUri, which is the route that Auth0 redirects to when a users signs in. This will be assigned the object window.location.origin, here the origin property will return the protocol, hostname and port number of the URL, essentially the current URL in our browser and after the login is complete it will direct us back to this URL.
![AuthProvider2](https://dev-to-uploads.s3.amazonaws.com/i/wb4ungaxcriqshocfv5m.png)

##Creating Login Button Component

Within react-auth, create a new folder called components that contains a file called LoginButton.js. In LoginButton.js create a React functional component skeleton.

Now this component is going to be using Auth0 so we need to import a hook created by Auth0 called useAuth0. We can then use this hook inside our function by de-structuring loginWithRedirect.

Finally, we want to return a button within JSX that when clicked will run the loginWithRedirect from Auth0. Your component should look like this:
![LoginButton](https://dev-to-uploads.s3.amazonaws.com/i/xpf3ibc0nkn0tos39v0x.png)

Now, import this component into app.js and add it in the return of App's functional component and run your application. You should see a login button on the page, when clicked it should direct you to Auth0's login page!
![AuthHome](https://dev-to-uploads.s3.amazonaws.com/i/6zpb1hrxr4cg9f6yjw8f.png)
 
## Creating Logout Button Component

The heavy lifting for this stage has already been done with the LoginButton.js.

All we need to do it copy the LoginButton.js in components and change the name to LogoutButton.js.

Within our LogoutButton, we need to change all instances of LoginButton to LogoutButton so go ahead and do that.

Lastly, in the component we need to de-structure logout from the useAuth0() instead of loginWithRedirect.

Your logout button is now fully functional! Import it within your App.js file and return it within the app functional component. Remember to wrap the return values within a div otherwise you will get an error!

Now the browser should be showing both the Login and Logout buttons.

## Making a User Profile

In order to understand what we can do with this login screen we'll display a simple user profile when logged in.

Here we need to make another component, copy the Logout.js component and rename this to Profile.js. Again, rename all instances of Logout to Profile.

We need to de-structure user and make it equal our useAuth0 hook, so go ahead and replace { logout } with { user }.

Now useAuth0 has been customised so that it will return us various user information, we just need to display it within the return value of the component. So instead of returning a button, here we want to return some JavaScript, because this is JSX we need to wrap the injected JavaScript in curly braces. Then we want to convert a JS object to JSON string so we will simply write:

`{JSON.stringify(user, null, 2)}`

Here, we are returning the JSON string with 3 parameters:
1. users - The value we want to convert to JSON string
2. null - The replacer, this means all the properties of the user are included in the string.
3. 2 - The white space used between the strings for readability.

Your component should look like this:
![Profile](https://dev-to-uploads.s3.amazonaws.com/i/h279ip4r5niite5snt4g.png)

Now import this within app.js, save, and check your browser, you should now see the user information in JSON format when logged in!

With this JSON information we can tailor our return value within the Profile functional component to show only specific information using dot notation.

So within the Profile component, comment out the JSON.stringify line and add an img tag with src attribute equal to {user.picture} and alt attribute = {user.name}.

Add {user.name} within a h2 tag and finally, add {user.email} within a h3 tag.

If you check the browser, you will see an error saying
>Cannot read property 'picture' of undefined
 This is because you are not logged in. So in order to bypass this error we need to pull out another property from useAuth0 called isAuthenticated:

`const {user, isAuthenticated} = useAuth0();`
 
 Once this is added we need to add an if statement to the return so that the return value renders if, and only if the user is authenticated. Your component should look like this:
![Authenticated](https://dev-to-uploads.s3.amazonaws.com/i/4tgon8kj0e5mzyige0wc.png)

Now check your browser, once logged in you should be able to see an image, name and email!

##Wrapping Up

This is just the tip of the iceberg with Auth0, a whistle stop tour of the authentication process. From this tutorial you can see how simple and effective Auth0 is to implement as well as use.