0

How to implement user access control in reactjs web app using routes.

From backend I am getting all the urls which is accessible to the logged-in user.

Like if a user1 is logged in and the data I am getting from backend

{
  0: {
    name: 'Homes', 
    uri: 'home', 
    menus: [
      0: { uri: 'home/dashboard', name: 'Dashboard' }
      1: { uri: 'home/people', name: 'People' }
      2: { uri: 'home/subject', name: 'Subject' }
    ]
  }

If another user logged in the data I am getting from backend

  0: {
    name: 'Homes', 
    uri: 'home', 
    menus: [
    0: { uri: 'home/dashboard', name: 'Dashboard' }
  ]
}


General Routing which I have already done:

<Router>
  <Routes>
   <Route path = '/home' element={<Users />} 
     <Route path = 'dashboard' element={<Dashboard />} />
     <Route path = 'people' element={<People />} />
     <Route path = 'subject' element={<Subject />} />
   />

  </Routes>
</Router>
devReact
  • 63
  • 6
  • What are you trying to accomplish? What have you tried or what is any issue you face? – Drew Reese Mar 29 '23 at 18:02
  • I am trying to restrict users to access urls or link. I am facing issue in initial logic. how do I implement this using backend data – devReact Mar 29 '23 at 18:12
  • Do you already have some code you are trying to use and need help with or do you just need to know how to implement general [route protection](https://stackoverflow.com/a/66289280/8690857)? – Drew Reese Mar 29 '23 at 18:13
  • I have already implemented general but need to put logic as per user login. Suppose user1 is loggedIn and have access to all urls. if user2 loggedIn and has access only one url(component) dashboard and people – devReact Mar 29 '23 at 18:20
  • I guess you could conditionally render the routes they have access to based on the fetched data, or update the protection component to search the data for a match to the current path and allow them through to the protected content. Can you [edit] to include a [mcve] for what you are trying to do? We can't really address issues with code we can't see. – Drew Reese Mar 29 '23 at 18:23
  • I have edited the question. Please have a look into it @DrewReese – devReact Mar 29 '23 at 18:37
  • It doesn't look like you are protecting *any* of the routes currently. Where does this user route data live in relation to where the routes are rendered? Are you using also this user route data to drive a navigation menu UI? I think you should try to include a more complete [mcve] so readers here aren't trying to guess what you or the code are trying to do. – Drew Reese Mar 29 '23 at 18:43
  • Sorry @DrewReese I have taken the wrong route name. – devReact Mar 29 '23 at 18:47
  • Yes I haven't used protected routing. This where I need help how can I use backend data and set protected routing – devReact Mar 29 '23 at 19:10
  • The "backend" data doesn't appear to be valid Javascript or JSON (*as written or copy/pasted*), what is the actual object/array structure in code? – Drew Reese Mar 29 '23 at 19:23
  • So is the data an array of objects, e.g. `[{ name: "...", uri: "...", menus: [{ uri: "...", name: "..." }, ...] }, ...]`? – Drew Reese Mar 29 '23 at 22:54
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/252859/discussion-between-devreact-and-drew-reese). – devReact Mar 29 '23 at 22:57
  • This question doesn't make sense. React is not an applicative framework - it is a UI component library. Asking "how to implement access control" and mentioning "routing" is misleading at best. – Eric MORAND Mar 30 '23 at 06:02

1 Answers1

0

You can create a protected route component that reads the received backend data object and compares this with the current route path being accessed. This is an example using a React context to provide the user data value and refactors the Users component to be the route protection component since it is the layout route for the nested user sub-routes.

const UserContext = createContext({
  user: null
});

const useUserContext = () => useContext(UserContext);

const UserContextProvider = ({ children }) => {
  const [user, setUser] = useState(null);

  ... Logic to set/clear the fetched user route access data

  return (
    <UserContext.Provider value={{ user }}>
      {children}
    </UserContext.Provider>
  );
};
<Routes>
  ...
  <Route path="/home" element={<Users />}>
    <Route path="dashboard" element={<Dashboard />} />
    <Route path="people" element={<People />} />
    <Route path="subject" element={<Subject />} />
    ...
  </Route>
  ...
</Routes>
const Users = () => {
  const { pathname } = useLocation();
  const { user } = useUserContext();

  const canAccessRoute = user?.menus.some(({ uri }) => uri === pathname);

  ...

  return canAccessRoute ? (
    <>
      ... Users UI ...
      <Outlet />
    </>
  ) : (
    <Navigate to="/" replace />
  );
};

Edit how-to-implement-user-access-control-in-reactjs-using-routes-as-per-backend-link

Drew Reese
  • 165,259
  • 14
  • 153
  • 181