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)
Thx for this, very helpful.
Good post Ben! Have you worked on using auth0's example on using PrivateRoute to prevent access to specific routes in an SPA?