0

I hope you are doing well!

I am trying out react-router-dom v6 with the public and private routes and this is the code I currently have

import { BrowserRouter, Routes, Route } from "react-router-dom";

import Login from "./user/pages/Login";
import { LoginRedirect } from "./auth/redirects/LoginRedirect";
import Home from "./shared/pages/Home";
import Authors from "./author/pages/Authors";
import Books from "./book/pages/Books";
import BookInformation from "./book/pages/BookInformation";
import CreateAuthor from "./author/pages/CreateAuthor";
import AuthorInformation from "./author/pages/AuthorInformation";
import { UserRoleRedirect } from "./auth/redirects/UserRoleRedirect";
import "./App.css";

function App() {
  return (
    <div className="App">
      <BrowserRouter>
        <Routes>
          <Route path="login" element={<Login />} />

          <Route path="/" element={<LoginRedirect />}>
            <Route path="/" element={<Home />} />
            <Route path="authors" element={<Authors />} />
            <Route path="books" element={<Books />} />
            <Route path="books/:bookId" element={<BookInformation />} />
          </Route>

          <Route path="/" element={<UserRoleRedirect />}>
            <Route path="authors/new" element={<CreateAuthor />} />
            <Route path="authors/:authorId" element={<AuthorInformation />} />
          </Route>
        </Routes>
      </BrowserRouter>
    </div>
  );
}

export default App;

and this is the code of my LoginRedirect

import React from "react";
import { useLocation, Navigate, Outlet } from "react-router-dom";

import { useAuth } from "../useAuth";

export const LoginRedirect = () => {
  const { user } = useAuth();

  const location = useLocation();

  if (user.email === "" || user.email === null || user.email === undefined)
    return <Navigate to="/login" state={{ from: location }} replace />;

  return <Outlet />;
};

and my UserRoleRedirect

import React from "react";
import { useLocation, Navigate, Outlet } from "react-router-dom";

import { useAuth } from "../useAuth";

export const UserRoleRedirect = () => {
  const { user } = useAuth();

  const location = useLocation();

  if (user.email === "" || user.email === null || user.email === undefined)
    return <Navigate to="/login" state={{ from: location }} replace />;

  if (user.roleType === "N")
    return <Navigate to="/" state={{ from: location }} replace />;

  return <Outlet />;
};

and my page is working fine; however, I want to make the login accessible only if the User is not logged in (I am not using any backend at the moment, I am only storing user values in redux for testing purposes) mostly because if I want to access '/books', I redirect the user to the login page if they are not logged in and on log in redirect them to the '/books' page. But if the User clicks the back button of the browser I want to return them to the Home page and not the log in page.

I tried wrapping the login route like the other routes and added a component that would test if logged in to redirect to the "/" path as follows

import React from "react";
import { useLocation, Navigate, Outlet } from "react-router-dom";

import { useAuth } from "../useAuth";

export const AuthenticationRedirect= () => {
  const { user } = useAuth();

  const location = useLocation();

  if (user.email !== "" && user.email !== null && user.email !== undefined)
    return <Outlet />;

  return <Navigate to="/" state={{ from: location }} replace />;
};

but the component rerendered infinitely and didn't work.

I could add a test in the component

if(user.email!=="")
return <Navigate to="/" />

but I want to see if there is a way to manage it from the routes themselves.

How can I make the /login route only accessible if user not logged in?

1 Answers1

0

The basic idea is to wrap routes that require authentication with a custom component (PrivateRoute in the example below). PrivateRoute will use some logic to determine if the user is authenticated and then either; allow the requested route to render, or redirect to the login page.

Attached link has the answer https://stackoverflow.com/a/47476903/4563919

Taimoor Tahir
  • 430
  • 4
  • 6