programing

리액트 라우터 v6에 의한 보호 루트

newsource 2023. 3. 11. 09:02

리액트 라우터 v6에 의한 보호 루트

리액트 라우터의 새로운 버전6을 사용하여 Protect Route를 작성하는 올바른 방법은 무엇입니까?이건 내가 썼는데 루트가 아니야

const PrivateRoute = ({ component: Component, ...props }) => {   
  if (!Component) return null;

  return props.isAuthenticated
    ? <Component />
    : <Navigate to={props.redirectLink} /> }

export default PrivateRoute;

다음으로 useRoutes를 사용하여 개인 루트를 구현하기 위한 작업 예를 나타냅니다.

App.js

import routes from './routes';
import { useRoutes } from 'react-router-dom';

function App() {
  const { isLoggedIn } = useSelector((state) => state.auth);

  const routing = useRoutes(routes(isLoggedIn));

  return (
    <>
      {routing}
    </>
  );
}

routes.displaces

import { Navigate,Outlet } from 'react-router-dom';

const routes = (isLoggedIn) => [
  {
    path: '/app',
    element: isLoggedIn ? <DashboardLayout /> : <Navigate to="/login" />,
    children: [
      { path: '/dashboard', element: <Dashboard /> },
      { path: '/account', element: <Account /> },
      { path: '/', element: <Navigate to="/app/dashboard" /> },
      {
        path: 'member',
        element: <Outlet />,
        children: [
          { path: '/', element: <MemberGrid /> },
          { path: '/add', element: <AddMember /> },
        ],
      },
    ],
  },
  {
    path: '/',
    element: !isLoggedIn ? <MainLayout /> : <Navigate to="/app/dashboard" />,
    children: [
      { path: 'login', element: <Login /> },
      { path: '/', element: <Navigate to="/login" /> },
    ],
  },
];

export default routes;

나는 이 예를 들었다.react-router-dom: https://github.com/remix-run/react-router/blob/main/examples/auth/README.md

다음으로 이 https://stackblitz.com/edit/github-5kknft?file=src%2FApp.tsx으로 변경합니다.

export default function App() {
  return (
    <AuthProvider>
      <Routes>
        <Route element={<Layout />}>
          <Route path="/" element={<PublicPage />} />
          <Route path="/public" element={<PublicPage />} />
          <Route path="/login" element={<LoginPage />} />
          <Route element={<RequireAuth />}>
            <Route path="/protected" element={<ProtectedPage />} />
            <Route path="/dashboard" element={<Dashboard />} />
          </Route>
        </Route>
        <Route path="*" element={<NotFound />} />
      </Routes>
    </AuthProvider>
  );
}
function RequireAuth() {
  let auth = useAuth();
  let location = useLocation();

  if (!auth.user) {
    // Redirect them to the /login page, but save the current location they were
    // trying to go to when they were redirected. This allows us to send them
    // along to that page after they login, which is a nicer user experience
    // than dropping them off on the home page.
    return <Navigate to="/login" state={{ from: location }} />;
  }

  return <Outlet />;
}

다음은 React Router 매뉴얼에 기재된 공식 가이드라인은 다음과 같습니다.

「 」의 래퍼를 에, 「 」의 합니다.<Route>은 모두 '을 해야 .<Route element>

위의 예를 들어 특정 루트를 React Router v6에서 인증되지 않은 사용자로부터 보호하는 경우 다음과 같이 할 수 있습니다.

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

function App() {
  return (
    <Routes>
      <Route path="/public" element={<PublicPage />} />
      <Route
        path="/protected"
        element={
          // Good! Do your composition here instead of wrapping <Route>.
          // This is really just inverting the wrapping, but it's a lot
          // more clear which components expect which props.
          <RequireAuth redirectTo="/login">
            <ProtectedPage />
          </RequireAuth>
        }
      />
    </Routes>
  );
}

function RequireAuth({ children, redirectTo }) {
  let isAuthenticated = getAuth();
  return isAuthenticated ? children : <Navigate to={redirectTo} />;
}

에서는, 「」가 어떻게 있는지에 해 주세요.RequireAuth 도 기대하지 않다<Route>의 소품입니다. 이것은 은은 a a a a a this this this this this this this a a 。<Route> 신, 것, 것, 것, 것, a, a, a, a, a, a, a, a, a이다.<Route>.

다음은 리액트 라우터 v6 베타 버전을 사용한 최신 구현입니다.단, useRoutes를 사용하여 보호된 루트를 구현하는 방법은 모릅니다.이들 문서에는 보호 루트/프라이빗 루트의 구현 방법에 대한 예가 기재되어 있습니다.

ProtectedRoute 컴포넌트

import React from 'react';
import PropTypes from 'prop-types';
import { Route } from 'react-router-dom';
import Forbidden from '../../views/errors/Forbidden';
import { useAuth } from '../../contexts/AuthContext';

const ProtectedRoute = ({ roles, element, children, ...rest }) => {
  const { user, login } = useAuth();

  if (!user) {
    login();
    return <></>;
  }

  if (roles.length > 0) {
    const routeRoles = roles.map((role) => role.toLowerCase());
    const userRoles = (user && user.roles ? user.roles : []).map((role) => role.toLowerCase());
    if (miscUtils.intersection(routeRoles, userRoles).length === 0) {
      return <Forbidden />;
    }
  }

  return (
    <Route element={element} {...rest}>
      {children}
    </Route>
  );
};

ProtectedRoute.propTypes = {
  roles: PropTypes.arrayOf(PropTypes.string),
  element: PropTypes.element,
  children: PropTypes.node,
};

ProtectedRoute.defaultProps = {
  roles: [],
  element: null,
  children: null,
};

export default ProtectedRoute;

AppRoutes 컴포넌트

import React from 'react';
import { Routes, Route, Navigate, Outlet } from 'react-router-dom';
import Login from './components/oauth/Login';
import Logout from './components/oauth/Logout';
import RenewToken from './components/oauth/RenewToken';
import ProtectedRoute from './components/ProtectedRoute';
import NotFound from './views/errors/NotFound';
import Index from './views/Index';
import MainContainer from './views/MainContainer';
import ViewUserProfile from './views/user/profile/ViewUserProfile';
import CreateUserProfile from './views/user/profile/CreateUserProfile';
import UpdateUserProfile from './views/user/profile/UpdateUserProfile';
import PartnerProfile from './views/partner/profile/PartnerProfile';

const AppRoutes = () => {
  return (
    <Routes>
      {/* auth pages (important: do not place under /auth path) */}
      <Route path="oauth/login" element={<Login />} />
      <Route path="oauth/logout" element={<Logout />} />
      <Route path="oauth/renew" element={<RenewToken />} />
      <Route element={<MainContainer />}>
        <Route path="/" element={<Index />} />

        {/* protected routes */}
        <ProtectedRoute path="user" element={<Outlet />}>
          <Route path="/" element={<Navigate to="profile" replace />} />

          <Route path="profile" element={<Outlet />}>
            <Route path="/" element={<ViewUserProfile />} />
            <Route path="create" element={<CreateUserProfile />} />
            <Route path="update" element={<UpdateUserProfile />} />
          </Route>
        </ProtectedRoute>

        <ProtectedRoute path="partner" roles={['partner']} element={<Outlet />}>
          <Route path="/" element={<Navigate to="profile" replace />} />
          <Route path="profile" element={<PartnerProfile />} />
        </ProtectedRoute>
      </Route>
      <Route path="*" element={<NotFound />} />
    </Routes>
  );
};

export default AppRoutes;

'아예'를 .Navigate또한 .

const Container = ({Component, redirectLink, isAuthenticated, ...props}) => {
  if(!isAuthenticated) {
       return <Navigate to={redirectLink} />;
   }
   
   return <Component {...props} />
}
const PrivateRoute = ({ component: Component, redirectLink, isAuthenticated, path, ...props }) => {   

  return (
    <Route
        path={path}
        element={<Container redirectLink={redirectLink} isAuthenticate={isAuthenticated} Component={Component} />}
    />
)

export default PrivateRoute;

이행 가이드라인은 다음 URL에서 확인할 수 있습니다.

모두 좋은 옵션입니다.또, 인증 상태(또는 그 외의 상태)에 근거해 다른 루트 처리를 간단하게 렌더링 할 수도 있습니다.raw Javascript 오브젝트 메서드를 사용할 필요가 없습니다.

함수를 사용할 수 (() => COMPONENT)() 컴포넌트를 <Route/>.

는 아직 예비 수 .v6 사적으로 하고 있기 때문입니다.<Route/>스스스님

예.

<Routes>
      {state.authed ?
        // Wait until we have the current user...
        currentUser ?
          <Route
            path='/'
            element={(() => {
              // Show a "no access" message if the user is NOT an App Admin doesn't have access to any schools at all (which includes not having access to anything INSIDE any school either)
              if (!currentUser.appAdministrator && currentUser.schoolIds?.length === 0) return <AdminNoAccess />
              return <Outlet />
            })()}
          >
            <Route
              path='/'
              element={(() => {
                // If the user is a super user, we return the <SuperAdmin /> component, which renders some of its own routes/nav.
                if (currentUser.appAdministrator) return <SuperAdmin />
                return <Outlet />
              })()}
            >
              <Route
                path='schools'
                element={(() => {
                  if (currentUser.schoolIds?.length === 1) {
                    return <Navigate to={`schools/schoolId`} />
                  } else {
                    return <AdminSchools />
                  }
                })()}
              />

              <Route path='users' children={<Users />} />
            </Route>

            <Route path={`schools/:schoolId`} element={<AdminSchool />} />

            <Route path='*' element={<Navigate to='schools' />} />
          </Route>
          :
          null
        :
        <>
          <Route path='login' element={<Login />} />
          <Route path='signup' element={<Signup />} />
          <Route path='forgot-password' element={<ForgotPassword />} />
          <Route path='reset-password' element={<ResetPassword />} />

          <Route path='*' element={<Navigate to='login' />} />
        </>
      }
    </Routes>

TypeScript를 하는 TypeScript를 더 한 것입니다.RouteProps "v6"로 합니다.

import React from 'react';
import { RouteProps } from 'react-router';
import { Route, Navigate } from 'react-router-dom';
import { useAuthState } from '../../contexts';

export interface PrivateRouteProps extends RouteProps {
  redirectPath: string;
}

export const PrivateRoute = ({ redirectPath, ...props }: PrivateRouteProps) => {
  const { user } = useAuthState();
  if (!user) {
    return <Navigate to={redirectPath} />;
  }
  return <Route {...props} />;
};

useAuthState하고 있는 할 수 입니다.

사용 방법은 다음과 같습니다.

<Routes>
  <Route path="/" element={<Home />} />
  <PrivateRoute path="/admin" redirectPath="/signin" element={<Admin />} />
  <Route path="*" element={<NotFound />} />
</Routes>

여기 작업 예가 있습니다.

import React from 'react';
import { Route, Navigate } from 'react-router-dom';

const PrivateRoute = ({ component: Component, redirectTo, isAuth, path, ...props }) => {
    if(!isAuth) {
        return <Navigate to={redirectTo} />;
    }
    return <Route path={path} element={<Component />} />
};

export default PrivateRoute;

사용방법:

<Routes>
     <Route path="app" element={<DashboardLayout />}>
         <PrivateRoute isAuth={true} path="account" component={AccountView}  redirectTo='/login'/>
     </Route>
 </Routes>

라우터로서의 Browser Router의 구조는 다음과 같습니다.

const AppRouter = () => {
  return (
    <Router>
      <Layout>
        <Routes>
          <Route exact path="" element={<Home />} />
          <Route exact path="login" element={<Login />} />
          <Route exact path="register" element={<Register />} />

          // These are the Private Components
          <Route
            exact
            path="/account"
            element={
              <PrivateRoute>
                <Account />
              </PrivateRoute>
            }
          />

          <Route
            exact
            path="/quizzes"
            element={
              <PrivateRoute>
                <Quizzes />
              </PrivateRoute>
            }
          />

          <Route
            exact
            path="/quizz/:quizzid"
            element={
              <PrivateRoute>
                <Quizz />
              </PrivateRoute>
            }
          />

          <Route
            exact
            path="/admin/users"
            element={
              <PrivateRoute>
                <Users />
              </PrivateRoute>
            }
          />
          <Route exact path="*" element={<NotFound />} />
        </Routes>
      </Layout>
    </Router>
  );
};

Private Route는 다음과 같습니다.

import { Navigate } from "react-router-dom";
import { useAuth } from "../auth/useAuth";

function PrivateRoute({ children }) {
  const auth = useAuth();
  return auth.user ? children : <Navigate to="/login" />;
}

export default PrivateRoute;

이것이 올바른 방법인지는 모르겠지만 실제로 개인 경로 구성요소는 필요하지 않습니다.다음과 같이 컴포넌트 내에 모든 개인 루트를 넣고 조건부로 렌더링할 수 있습니다.다음 코드에서는 Private 컴포넌트 내의 모든 프라이빗루트와 Public 컴포넌트 내의 모든 오픈루트를 입력합니다.

function RootRouter() {

  return (
    <div>
      <Router>
        {isLoggedIn ? <PrivateRouter /> : <PublicRouter />}
      </Router>
    </div>
  );
}

function PrivateRouter(props) {
  return (
    <div>
      <ToastContainer autoClose={3000} hideProgressBar />
      <NavBar />
      <Routes>
        <Route path="/" exact element={<Home />} />
        <Route path="/add" element={<Add />} />
        <Route path="/update/:id" element={<Add />} />
        <Route path="/view/:id" element={<Employee />} />
      </Routes>
    </div>
  );
}

function PublicRouter() {
  return (
    <Routes>
      <Route path="/" element={<Login />} />
    </Routes>
  );
}

스위치 케이스를 사용하여 사용자의 역할에 따라 접근을 허용할 수도 있습니다.

주의: 별도의 컴포넌트를 작성하지 않습니다.실제로 모든 루트를 1개의 컴포넌트에 넣고 동일한 조건으로 렌더링할 수 있습니다.

「」를 사용해 .replace속성: 사용자가 Back 브라우저 버튼을 사용할 수 없도록 합니다.

Private Route.js

import { Navigate } from 'react-router-dom';

const PrivateRoute = ({ currentUser, children, redirectTo }) => {
  if (!currentUser) return <Navigate to={redirectTo} replace />;

  return children;
};

export default PrivateRoute;

구현:

<Routes>
   <Route path='signIn' element={
            <PrivateRoute currentUser={currentUser} redirectTo='/'>
              <SignInAndSignUpPage />
            </PrivateRoute>
          }
        />
<Routes/>

react-router-dom 버전6의 PrivateRoute 코드를 올바르게 기술하는 방법은 다음과 같습니다.PrivateRoute.js 파일:

import React from "react";
import { Navigate } from "react-router-dom";
import { useAuth } from "./contexts/AuthContext";

export { PrivateRoute };

function PrivateRoute({ children }) {

const { currentUser } = useAuth();

if (!currentUser) {
    return <Navigate to="/" />
}
return children;
}

App.js 파일의 라우팅:

import { Routes, Route, Navigate } from 'react-router-dom';

import { PrivateRoute } from '_components';
import { Home } from 'home';
import { Login } from 'login';

export { App };

function App() {
return (
    <div className="app-container bg-light">
        <div className="container pt-4 pb-4">
            <Routes>
            <Route
                    path="/"
                    element={
                        <PrivateRoute>
                            <Home />
                        </PrivateRoute>
                    }
                />
                <Route path="/login" element={<Login />} />
                <Route path="*" element={<Navigate to="/" />} />
            </Routes>
        </div>
    </div>
);
}

하면 .auth-react-router패키지 https://www.npmjs.com/package/auth-react-router

루트를 정의하는 매우 간단한 API와 몇 가지 추가 설정(허가 및 무허가 루트의 리다이렉트루트, 각 루트의 폴백컴포넌트 등)을 제공합니다.

사용방법:

  1. 루트의 정의
// routes.tsx

import React from 'react';
import { IRoutesConfig } from 'auth-react-router';
import LoginPage from '../pages/LoginPage.tsx';

// public lazy loaded pages
const LazyPublicPage = React.lazy(() => import('../pages/PublicPage.tsx'));

// private lazy loaded pages
const LazyPrivatePage = React.lazy(() => import('../pages/PrivatePage.tsx'));
const LazyProfilePage = React.lazy(() => import('../pages/ProfilePage.tsx'));


export const routes: IRoutesConfig = {
  publicRedirectRoute: '/profile', // redirect to `/profile` when authorized is trying to access public routes
  privateRedirectRoute: '/login', // redirect to `/login` when unauthorized user access a private route
  defaultFallback: <MyCustomSpinner />,
  public: [
    {
      path: '/public',
      component: <LazyPublicPage />,
    },
    {
      path: '/login',
      component: <LoginPage />,
    },
  ],
  private: [
    {
      path: '/private',
      component: <LazyPrivatePage />,
    },
    {
      path: '/profile',
      component: <LazyProfilePage />
    },
  ],
  common: [
    {
      path: '/',
      component: <p>common</p>,
    },
    {
      path: '*',
      component: <p>page not found 404</p>,
    },
  ],
};
  1. 어플리케이션에 링크하다
import { AppRouter, Routes } from 'auth-react-router';
import { BrowserRouter } from 'react-router-dom';
import { routes } from './routes';

export const App = () => {
  const { isAuth } = useAuthProvider();
  return (
    <BrowserRouter>
      <AppRouter isAuth={isAuth} routes={routes}>
        {/* Wrap `Routes` component into a Layout component or add Header */}
        <Routes />
      </AppRouter>
    </BrowserRouter>
  );
};

위의 모든 방법을 사용하려고 했는데 왜 아무 것도 효과가 없는지 모르겠어요.드디어 해결했습니다.이것에 대한 저의 해결방법은 다음과 같습니다.

먼저 AdminRoute.js라는 이름의 파일을 src 어딘가에 있는 "routes" 폴더에 만듭니다.

import { Typography } from "@mui/material";
import React, { useEffect, useState } from "react";
import { useSelector } from "react-redux";
import { Navigate } from "react-router-dom";
import { currentAdmin } from "../../functions/auth";
import LoadingToRedirect from "./LoadingToRedirect";

const AdminRoute = ({ children }) => {
  const { user } = useSelector((state) => ({
    ...state,
  }));
  const [ok, setOk] = useState(false);

  useEffect(() => {
    if (user && user.token) {
      currentAdmin(user.token)
        .then((res) => {
          console.log("CURRENT ADMIN RES", res);
          setOk(true);
        })
        .catch((err) => {
          console.log("ADMIN ROUTE ERR", err);
          setOk(false);
        });
    }
  }, [user]);
  return ok ? children : <LoadingToRedirect />;
};

export default AdminRoute;

여기서 사용자가 언제 리다이렉트할지 언제 리다이렉트하지 않을지를 결정하는 독자적인 논리를 설정할 수 있습니다.제 경우처럼 api 호출을 한 번 함으로써 사용자의 역할이 관리자인지 여부를 확인하고 있습니다.

그런 다음 LoadingToRedirect.js 파일을 동일한 "routes" 폴더에 만듭니다.

import React, { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";

const LoadingToRedirect = () => {
  const [count, setCount] = useState(5);
  let navigate = useNavigate();

  useEffect(() => {
    const interval = setInterval(() => {
      setCount((currentCount) => --currentCount);
    }, 1000);
    // redirect once count is equal to 0
    count === 0 && navigate("/");
    // cleanup
    return () => clearInterval(interval);
  }, [count, navigate]);

  return (
    <div className="container p-5 text-center">
      <p>Redirecting you in {count} seconds</p>
    </div>
  );
};

export default LoadingToRedirect;

이제 App.js에서 App.js를 설정합니다.

여기서 '/check' URL로 이동하면 개인 경로 기능이 작동하여 사용자가 'admin'인지 여부를 확인합니다.페이지는 보호 대상이며 '자녀' 역할을 합니다.

<Routes>
          <Route
            path="/check"
            element={
              <AdminRoute>
                <Check />
              </AdminRoute>
            }
          />

     
          <Route path="*" element={<NotFound />} />
        </Routes>

바로 그거야 넌 떠날 준비가 됐어건배!!

이건 나한테 효과가 있었어.

const protectedPages = [
    { path: '/packages', page: <PackagesPage /> },
    { path: '/checkout', page: <CheckoutPage /> },
    { path: '/checkout/success', page: <CheckoutSuccessPage /> },
];

function App() {
    return (
        <BrowserRouter>
            <Routes>
                <Route path='/' element={<AuthPage />} />

                {/* Programmatically protect routes */}
                {protectedPages.map((p, i) => (
                    <Route
                        path={p.path}
                        element={<RequireAuth>{p.page}</RequireAuth>}
                        key={i}
                    />
                ))}

                <Route path='*' element={<PageNotFound />}></Route>
            </Routes>
        </BrowserRouter>
    );
}

const RequireAuth = ({ children }) => {
    const navigate = useNavigate();
    const { id } = useSelector(selectUser);

    React.useEffect(() => {
        if (!id) {
            navigate('/');
        }
    }, [id, navigate]);

    return children;
};

export default App;

사용자가 인증되지 않은 경우 루트 자체를 메인루트에서 삭제하려는 경우 이를 사용할 수 있습니다.

// dummy routes
const domainRoutes = [
  {
    index: true,
    path: "Profile",
    element: <Profile/>,
    hidden: true,
  },
  {
    path: "*",
    element: <AuthGuard />,
  },
];

// recursive function which remove routes from default which has hidden key as true, so if user tried to access routes that is not defined we can so then auth gurad or forbidden page

const Auth = ({ routes }) => {
  const removeisHiddenItems = (array) => {
    const validateHidden = (item) => {
      return item.isHidden;
    };
    return array.reduce((acc, item) => {
      // acc -> short for "accumulator" (array)
      // item -> the current array item
      if (validateHidden(item)) {
        return acc;
      } else if (item.children) {
        var children = removeisHiddenItems(item.children);
        if (children.length) acc.push(Object.assign({}, item, { children }));
      } else {
        if (!validateHidden(item)) {
          acc.push(item);
        }
      }
      return acc;
    }, []);
  };

  const filterRoutes = removeisHiddenItems(routes);
  const content = useRoutes(filterRoutes);
  return content;
};

const App = () => {
  return (
    <>
      <CssBaseline />
      <ThemeProvider theme={currentTheme}>
        <Auth routes={currentContent} />
      </ThemeProvider>
    </>
  );
};

export default App;

경로를 래핑하는 대신 다음과 같이 래퍼 컴포넌트를 사용할 수 있습니다.

index.displaces를 표시합니다.

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <StoreProvider>
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<App />}>
          <Route index element={<Home />} />
          <Route path="/login" element={<Login />} />
          <Route path="/register" element={<Registration />} />
          <Route path="/account" element={<Account />}>
            <Route index element={<AccountUser />} />
            <Route path="garage" element={<AccountGarage />} />
            <Route path="garage/addcar" element={<Guard component={<AddCar />} userRole="USER" />} />
            <Route path="garage/mycars" element={<Guard component={<MyCars />} userRole="USER" />} />
            <Route path="garage/addrepair" element={<Guard component={<AddRepair />} userRole="SERVICE" />} />
            <Route path="garage/myshop" element={<Guard component={<MyShop />} userRole="SERVICE" />} />
            <Route path="help" element={<AccountHelp />} />
            <Route path="settings" element={<AccountSettings />} />
          </Route>
          <Route path="/response" element={<Response />} />
          <Route path="password-reset/:token" element={<Reset />} />
          <Route path="*" element={<Navigate to="/" />} />
        </Route>
      </Routes>
    </BrowserRouter>
  </StoreProvider>

Guard.jsx

import React from 'react';
import { Navigate } from 'react-router-dom';
import { useStore } from '../utils/store';

export default function Guard({component, userRole}) {
    const [{ user: { role}},] = useStore();
    return role === userRole ? component : <Navigate to="/"/>
}

최근에는 리액트 라우터 버전6의 루트 보호 문제도 있었습니다.그리고 사용자 인증 프로세스에 AUth0을 사용하고 있었습니다.그래서 저는 그것을 3단계로 고쳤습니다.

  1. History.js 페이지를 생성하여 createBrowserHistory-를 사용합니다.
import { createBrowserHistory } from "history";
export default createBrowserHistory();
  1. 다음으로 PrivateRoute.js에서 "isAuthenticated"를 사용하여 로그인했는지 여부를 확인했습니다.
  2. 그리고 App.js에서는 Route와 Routes를 이렇게 사용했습니다.
    <Routes>
        <Route path="/" exact element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/contact" element={<Contact />} />
        <Route path="/blog" element={<Posts />} />
        <Route element={<PrivateRoute/>}>
         <Route path="/dashboard" element={<Profile/>} />
              {/* Other Routes you want to protect */}
        </Route>
    </Routes>

이 솔루션은 블로그에 기재되어 있습니다.Auth0 보호 경로 구현

언급URL : https://stackoverflow.com/questions/62384395/protected-route-with-react-router-v6