For this you have to add rule in auth0 dashboard: https://auth0.com/docs/customize/rules. I wrote a custom rule function in this post
Then write a HOC:
function withAuth<T>(Component: React.ComponentType<T>) {
return (role: string) => {
return (props: T) => {
// CUSTOM HOOK TO GET THE USER
const { data, loading } = useGetUser();
if (loading) {
return <p>Loading...</p>;
}
if (!data) {
return <Redirect to="/api/v1/login" />;
} else {
if (role && !isAuthorized(data, role)) {
return <Redirect to="/api/v1/login" />;
}
return <Component user={data} loading={loading} {...props} />;
}
};
};
}
export default withAuth;
isAuthorized:
import { Claims } from "@auth0/nextjs-auth0/dist/session/session";
export const isAuthorized = (user: Claims, role: string) => {
return (
user &&
// user[process.env.AUTH0_NAMESPACE + "/roles"] &&
user["https://yourdomain.auth.com" + "/roles"].includes(role)
);
};
useGetUser Hook
export const useGetUser = () => {
// "/api/v1/me" is passed to fetcher as url
const { data, error, ...rest } = useSWR("/api/v1/me", fetcher);
return { data, error, loading: !data && !error, ...rest };
};
fetcher for useSWR
export const fetcher = (url: string) =>
fetch(url).then(
async (res: Response): Promise<any> => {
const result = await res.json();
if (res.status !== 200) {
return Promise.reject(result);
} else {
return result;
}
}
);
/api/v1/me api function in pages.
// you should already have set auth) instance
import auth0 from "@/utils/auth0";
import { NextApiRequest, NextApiResponse } from "next";
export default async function me(req: NextApiRequest, res: NextApiResponse) {
try {
await auth0.handleProfile(req, res);
} catch (error) {
console.log("error in v1/me ", error);
res.status(error.status || 400).end(error.message);
}
}
After this set up you can wrap your components with withAuth
const Dashboard: React.FC<DashboardProps> = ({ user, loading }) => {
return (
<BaseLayout
>
<BasePage >
{/* YOUR COMPONENT LOGIC HERE */}
</BasePage>
</BaseLayout>
);
};
export default withAuth(Dashboard)("admin");