Next.js: Role access / claim check using withPageAuthRequired

I’m using GitHub - auth0/nextjs-auth0: Next.js SDK for signing in with Auth0 and I’d like to use withPageAuthRequired (or similar ) to be able to conditionally disallow someone access to a page based on the result of a function. Within that function, I’m imagining that I’ll read the session and grab their role from it.

Similar to the examples here: helpers/with-page-auth-required | @auth0/nextjs-auth0

But one step further… I want to be able to return a 401 or some error component for pages their not allowed to access.

I tried this: withAuthenticationRequired's claimsCheck causing infinite loop in Next.js SPA · Issue #320 · auth0/auth0-react · GitHub
But it does not work in next.js since that solution is for the react version of the library. Not only that but useUser or useAuth0 won’t work since these are hooks that can only be used in a react component.

Looks like the react library allows you to implement a claimCheck via WithAuthenticationRequiredOptions. (src: WithAuthenticationRequiredOptions | @auth0/auth0-react) Can it be done the same way for next or do I need to awkwardly mix the libraries?

I’m sure it must be possible with the options around withPageAuthRequired - but I can’t seem to figure it out.
Any and all tips greatly appreciated. Thanks

Think I’ve managed to solve this one myself.

I basically figured I should be able to make a HOC that wraps withPageAuthRequired and returns a particular page based on checking roles (or anything you wish) from the user object. I called this HOC withRoleAuthorization

This works pretty well for my needs, I hope it works well for others, too:

const withRoleAuthorization = (
  Success,
  allowedRoles,
  Err,
  onError,
  onRedirecting,
  returnTo
) => {

  function hoc({ user }) {
    function arrContains(arr1, arr2) {
      return arr1.some(item => arr2.includes(item))
    }

    // check if the array of roles for a user contains any of the roles for the allowed array 
    // for the page.
    const usersRoles = user['http://mysite.com/roles']
    if (!arrContains(usersRoles, allowedRoles)){
      return (<Err />)
    }
    return (<Success user={user} />);
  }
  // https://auth0.github.io/nextjs-auth0/interfaces/frontend_with_page_auth_required.withpageauthrequiredoptions.html
  return withPageAuthRequired(hoc, {onError, onRedirecting, returnTo})
}

Then this can be used in a page like so:

function Profile({ user }) {
// we can use the user prop if we want it now, too :)
  return (
    <>
     <p>stuff here</p>
    </>
  );
}

// use of withRoleAuthorization - wrap your exported page component with it
export default withRoleAuthorization(Profile, ["admin", "somerole"], () => (<h1>nope!</h1>))

You’re welcome ! :stuck_out_tongue:

Pass withRoleAuthorization:

  • the page component your doing role based access on,
  • a list of roles that are allowed to access that page,
  • and an error component that will be shown if the user doesn’t have that role, and is not allowed to access that page.

Can optionally pass in onError, onRedirecting, returnTo - so they can be fed into withPageAuthRequired.

Let me know if people think this can be improved!