Extremely easy client-side authentication with React and Auth0
Tags: react, authentication, auth0
Published: 2020-01-18 16:32:19


I've been using auth0 for almost 3 years on various projects, including across [The People Experience Hub](https://pxhub.io) survey platform. However I have always used a server-side implementation.

I recently decided to explore the client side implementation with React, and although the [React Auth0 tutorial](https://auth0.com/docs/quickstart/spa/react/01-login) is very clear, it seemed a bit overkill to me for simpler use cases.

I did some experimenting and managed to come up with an approach that only requires you to install Auth0's SPA package. Without setting up `react-router` (which may not be needed for smaller apps). 

_DISCLAIMER - I came up with this approach after hacking together a small React project which is not yet in production. Any feedback, or reasons why this approach is not a good idea would be great :)_

Start off by installing `@auth0/auth0-spa-js`
```
npm install @auth0/auth0-spa-js
```

Then in your `index.js` file
```js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import createAuth0Client from "@auth0/auth0-spa-js";

// render loading message whilst we determine if we have an authenticated user
ReactDOM.render(<p>Loading...</p>, document.getElementById('root'));

const auth0Options = {
    domain: 'YOUR_AUTH0_DOMAIN',
    client_id: 'YOUR_AUTH0_CLIENT_ID',
    redirect_uri: 'REDIRECT_URI'
}

// initiate auth0 client
createAuth0Client(auth0Options).then(async (auth0) => {
    // if user is already logged in, this will return the user
    let user = await getUser(auth0);

    if (!user) {
        try {
            // if no user, try to handle call back
            await auth0.handleRedirectCallback();
            user = await getUser();
            // remove callback token from query string
            window.location.search = '';
        } catch (error) {
            // on error, assume user is not logged in
            console.log(error);
            console.log('user not logged in');

            const UnAuthApp = ({auth0}) => (
                <React.Fragment>
                    <h1>Log in</h1>
                    <button onClick={async () => await auth0.loginWithRedirect()}>Log in</button>
                </React.Fragment>
            )
            // render un-authenticated component
            ReactDOM.render(<UnAuthApp auth0={auth0} />, document.getElementById('root'));
            return;
        }
    }

    // if we get to this line, then we have an authenticated user
    ReactDOM.render(<App auth0={auth0} user={user} />, document.getElementById('root'));
});

const getUser = async (auth0) => {
    try {
        const accessToken = await auth0.getTokenSilently();
        const user = await auth0.getUser();
        return { ...user, accessToken };
    } catch (error) {
        console.log(error);
        return;
    }
}

```

☝️ This could do with some tidying up, but I left it like this to give the whole example in one file.

I put together a demo repo using `create-react-app` [here](https://github.com/ben-cloud9/react-easy-auth0-example)