DEV Community

Ben Keating
Ben Keating

Posted on

Extremely easy client-side authentication with React and Auth0

I've been using auth0 for almost 3 years on various projects, including across The People Experience Hub 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 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

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

Top comments (2)

Collapse
 
tyson3101 profile image
Tyson3101

Thx for this, very helpful.

Collapse
 
deanagan profile image
Dean

Good post Ben! Have you worked on using auth0's example on using PrivateRoute to prevent access to specific routes in an SPA?