- Use with a Class Component
- Protect a Route
- Call an API
- Protecting a route in a
react-router-dom v6
app - Protecting a route in a Gatsby app
- Protecting a route in a Next.js app (in SPA mode)
- Use with Auth0 organizations
- Protecting a route with a claims check
Use the withAuth0
higher order component to add the auth0
property to Class components:
import React, { Component } from 'react';
import { withAuth0 } from '@auth0/auth0-react';
class Profile extends Component {
render() {
// `this.props.auth0` has all the same properties as the `useAuth0` hook
const { user } = this.props.auth0;
return <div>Hello {user.name}</div>;
}
}
export default withAuth0(Profile);
Protect a route component using the withAuthenticationRequired
higher order component. Visits to this route when unauthenticated will redirect the user to the login page and back to this page after login:
import React from 'react';
import { withAuthenticationRequired } from '@auth0/auth0-react';
const PrivateRoute = () => <div>Private</div>;
export default withAuthenticationRequired(PrivateRoute, {
// Show a message while the user waits to be redirected to the login page.
onRedirecting: () => <div>Redirecting you to the login page...</div>,
});
Note If you are using a custom router, you will need to supply the Auth0Provider
with a custom onRedirectCallback
method to perform the action that returns the user to the protected page. See examples for react-router, Gatsby and Next.js.
Call a protected API with an Access Token:
import React, { useEffect, useState } from 'react';
import { useAuth0 } from '@auth0/auth0-react';
const Posts = () => {
const { getAccessTokenSilently } = useAuth0();
const [posts, setPosts] = useState(null);
useEffect(() => {
(async () => {
try {
const token = await getAccessTokenSilently({
authorizationParams: {
audience: 'https://api.example.com/',
scope: 'read:posts',
},
});
const response = await fetch('https://api.example.com/posts', {
headers: {
Authorization: `Bearer ${token}`,
},
});
setPosts(await response.json());
} catch (e) {
// Handle errors such as `login_required` and `consent_required` by re-prompting for a login
console.error(e);
}
})();
}, [getAccessTokenSilently]);
if (!posts) {
return <div>Loading...</div>;
}
return (
<ul>
{posts.map((post, index) => {
return <li key={index}>{post}</li>;
})}
</ul>
);
};
export default Posts;
We need to access the useNavigate
hook so we can use navigate
in onRedirectCallback
to return us to our returnUrl
.
In order to access useNavigate
when defining our Auth0Provider
we must nest it in BrowserRouter
and use the navigate method from the hook in our onRedirectCallback
config.
We can then use the withAuthenticationRequired
HOC (Higher Order Component) to create a ProtectedRoute
component that redirects anonymous users to the login page, before returning them to the protected route:
import React from 'react';
import { Route, BrowserRouter, Routes, useNavigate } from 'react-router-dom';
import { Auth0Provider, withAuthenticationRequired } from '@auth0/auth0-react';
import Profile from './Profile';
const ProtectedRoute = ({ component, ...args }) => {
const Component = withAuthenticationRequired(component, args);
return <Component />;
};
const Auth0ProviderWithRedirectCallback = ({ children, ...props }) => {
const navigate = useNavigate();
const onRedirectCallback = (appState) => {
navigate((appState && appState.returnTo) || window.location.pathname);
};
return (
<Auth0Provider onRedirectCallback={onRedirectCallback} {...props}>
{children}
</Auth0Provider>
);
};
export default function App() {
return (
<BrowserRouter>
<Auth0ProviderWithRedirectCallback
domain="YOUR_AUTH0_DOMAIN"
clientId="YOUR_AUTH0_CLIENT_ID"
authorizationParams={{
redirect_uri: window.location.origin,
}}
>
<Routes>
<Route path="/" exact />
<Route
path="/profile"
element={<ProtectedRoute component={Profile} />}
/>
</Routes>
</Auth0ProviderWithRedirectCallback>
</BrowserRouter>
);
}
Wrap the root element in your Auth0Provider
to configure the SDK and setup the context for the useAuth0
hook.
The onRedirectCallback
will use gatsby
's navigate
function to return the user to the protected route after the login:
// gatsby-browser.js
import React from 'react';
import { Auth0Provider } from '@auth0/auth0-react';
import { navigate } from 'gatsby';
const onRedirectCallback = (appState) => {
// Use Gatsby's navigate method to replace the url
navigate(appState?.returnTo || '/', { replace: true });
};
export const wrapRootElement = ({ element }) => {
return (
<Auth0Provider
domain="YOUR_AUTH0_DOMAIN"
clientId="YOUR_AUTH0_CLIENT_ID"
onRedirectCallback={onRedirectCallback}
authorizationParams={{
redirect_uri: window.location.origin,
}}
>
{element}
</Auth0Provider>
);
};
Create a page that you want to be protected, e.g. a profile page, and wrap it in the withAuthenticationRequired
HOC:
// src/pages/profile.js
import React from 'react';
import { useAuth0, withAuthenticationRequired } from '@auth0/auth0-react';
const Profile = () => {
const { user } = useAuth0();
return (
<ul>
<li>Name: {user.nickname}</li>
<li>E-mail: {user.email}</li>
</ul>
);
};
// Wrap the component in the withAuthenticationRequired handler
export default withAuthenticationRequired(Profile);
Wrap the root element in your Auth0Provider
to configure the SDK and setup the context for the useAuth0
hook.
The onRedirectCallback
will use next
's Router.replace
function to return the user to the protected route after the login:
// pages/_app.js
import React from 'react';
import App from 'next/app';
import Router from 'next/router';
import { Auth0Provider } from '@auth0/auth0-react';
const onRedirectCallback = (appState) => {
// Use Next.js's Router.replace method to replace the url
Router.replace(appState?.returnTo || '/');
};
class MyApp extends App {
render() {
const { Component, pageProps } = this.props;
return (
<Auth0Provider
domain="YOUR_AUTH0_DOMAIN"
clientId="YOUR_AUTH0_CLIENT_ID"
onRedirectCallback={onRedirectCallback}
authorizationParams={{
redirect_uri:
typeof window !== 'undefined' ? window.location.origin : undefined,
}}
>
<Component {...pageProps} />
</Auth0Provider>
);
}
}
export default MyApp;
Create a page that you want to be protected, e.g. a profile page, and wrap it in the withAuthenticationRequired
HOC:
// pages/profile.js
import React from 'react';
import { useAuth0, withAuthenticationRequired } from '@auth0/auth0-react';
const Profile = () => {
const { user } = useAuth0();
return (
<ul>
<li>Name: {user.nickname}</li>
<li>E-mail: {user.email}</li>
</ul>
);
};
// Wrap the component in the withAuthenticationRequired handler
export default withAuthenticationRequired(Profile);
Organizations is a set of features that provide better support for developers who build and maintain SaaS and Business-to-Business (B2B) applications. Note that Organizations is currently only available to customers on our Enterprise and Startup subscription plans.
To log the user in to an organization, you should specify the organization in the Auth0Provider
props.
ReactDOM.render(
<React.StrictMode>
<Auth0Provider
domain="YOUR_AUTH0_DOMAIN"
clientId="YOUR_AUTH0_CLIENT_ID"
authorizationParams={{
organization: "YOUR_ORGANIZATION_ID_OR_NAME"
redirectUri: window.location.origin,
}}
>
<App />
</Auth0Provider>
</React.StrictMode>,
document.getElementById('root')
);
To accept an invite from an organization, you should call loginWithRedirect
with the invitation
and organization
parameters.
import React from 'react';
import ReactDOM from 'react-dom';
import { Auth0Provider, useAuth0 } from '@auth0/auth0-react';
const App = () => {
const { loginWithRedirect } = useAuth0();
const url = window.location.href;
const inviteMatches = url.match(/invitation=([^&]+)/);
const orgMatches = url.match(/organization=([^&]+)/);
if (inviteMatches && orgMatches) {
loginWithRedirect({
authorizationParams: {
organization: orgMatches[1],
invitation: inviteMatches[1],
}
});
}
return <div>...</div>;
};
In order to protect a route with a claims check alongside an authentication required check, you can create a HOC that will wrap your component and use that to check that the user has the required claims.
const withClaimCheck = (Component, myClaimCheckFunction, returnTo) => {
const { user } = useAuth0();
if (myClaimCheckFunction(user)) {
return <Component />
}
Router.push(returnTo);
}
const checkClaims = (claim?: User) => claim?.['https://my.app.io/jwt/claims']?.ROLE?.includes('ADMIN');
// Usage
const Page = withAuthenticationRequired(
withClaimCheck(Component, checkClaims, '/missing-roles' )
);