Protect route with role in React

I have setup a rule which injects roles into the idTokenClaim. I can now conditionally render components based on these roles but I would like to protect a route based on the roles. Is there a way to use withAuthenticationRequired but also require specific roles?

Hi @gidon,

Welcome to the Community!

I don’t believe there is a built-in way to protect routes based on roles in the React SDK, however, I was able to find this example that a colleague wrote. This code creates a withRoleBasedRedirect wrapper for components. I haven’t tested this out, but hopefully this provides you with some ideas for your own implementation:

import React, { FC } from 'react';
import { ComponentType, useState, useEffect } from "react";
import { useHistory } from 'react-router-dom';
import { useAuth0 } from '@auth0/auth0-react';
export interface WithRoleBasedRedirectOptions {
  role: string;
}
const roleClaimType = 'https://demo.com/roles';
export const withRoleBasedRedirect = <P extends object>(
  Component: ComponentType<P>,
  options: WithRoleBasedRedirectOptions
): FC<P> => (props: P): JSX.Element => {
  const history = useHistory();
  const { getIdTokenClaims } = useAuth0();
  const [isAuthorized, setIsAuthorized] = useState(false);
  useEffect(() => {
    async function getRoles(): Promise<Array<string>> {
      const claims = await getIdTokenClaims();
      return claims[roleClaimType] || [];
    }
    async function checkRoles(role: string) {
      const roles = await getRoles();
      const isAuthorized = roles.includes(role);
      if (!isAuthorized) {
        history.push('/not-authorized');
      } else {
        setIsAuthorized(true);
      }
    }
    checkRoles(options.role);
  }, [getIdTokenClaims, history]);
  return isAuthorized ? <Component {...props} /> : <div></div>;
};
import React from "react";
import { Route } from "react-router-dom";
import { withAuthenticationRequired } from "@auth0/auth0-react";
import Loader from "../Loader/Loader";
import { withRoleBasedRedirect } from "../withRoleBasedRedirect/withRoleBasedRedirect";
export const ProtectedRoute = ({ component, role, ...args }: any) =>
  role ? (
    <Route
      component={withAuthenticationRequired(
        withRoleBasedRedirect(component, { role }),
        {
          onRedirecting: () => <Loader />,
        }
      )}
      {...args}
    />
  ) : (
    <Route
      component={withAuthenticationRequired(component, {
        onRedirecting: () => <Loader />,
      })}
      {...args}
    />
  );

route configuration:

<BrowserRouter>
  <ProtectedRoute path="/" exact role="Admin" component={UserPage} />
  <ProtectedRoute
      path="/not-authorized"
      exact
      component={NotAuthorized}
   />
</BrowserRouter>

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.