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
 
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?

Collapse
 
tyson3101 profile image
Tyson3101 •

Thx for this, very helpful.