受保护的路由不路由react-router-dom

问题描述 投票:0回答:1

我在我的 React 应用程序中使用 React-router-dom 进行路由。我现在想创建一个受保护的路由,这样只有登录后才能访问某些页面。但目前我仍然可以访问受保护的页面,并且登录后不会从登录页面重定向到仪表板

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import {
    BrowserRouter as Router,
    Routes,
    Route,
    Navigate,
} from 'react-router-dom';
import axios from 'axios';
import { UserContextProvider } from './context/userContext';
import { ToastProvider } from './context/toastContext';
import { DialogProvider } from './context/dialogContext';
import ProtectedRoute from './components/protectedRoute';
import Register from './pages/auth/register';
import Profile from './pages/profile';
import Friends from './pages/friends';
import Notifications from './pages/notifications';
import Landingpage from './pages/landingpage';
import Dashboard from './pages/dashboard';
import Login from './pages/auth/login';
import './index.css';

const routes = [
    { path: '/home', element: Landingpage },
    { path: '/dashboard', element: Dashboard, protected: true },
    { path: '/login', element: Login },
    { path: '/register', element: Register },
    { path: '/profile', element: Profile, protected: true },
    { path: '/friends', element: Friends, protected: true },
    { path: '/notifications', element: Notifications, protected: true },
    { path: '/', element: Navigate, to: '/home' },
];

axios.defaults.baseURL = 'http://localhost:8000';
axios.defaults.withCredentials = true;

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <UserContextProvider>
        <ToastProvider>
            <DialogProvider>
                <Router>
                    <Routes>
                        {routes.map((route, index) => {
                            if (route.protected) {
                                return (
                                    <Route
                                        key={index}
                                        path={route.path}
                                        element={
                                            <ProtectedRoute
                                                element={route.element}
                                            />
                                        }
                                    />
                                );
                            }
                            return (
                                <Route
                                    key={index}
                                    path={route.path}
                                    element={<route.element to={route.to} />}
                                />
                            );
                        })}
                    </Routes>
                </Router>
            </DialogProvider>
        </ToastProvider>
    </UserContextProvider>
);

protectedRoute.jsx

import React, { useContext } from 'react';
import { Navigate } from 'react-router-dom';
import { UserContext } from '../context/userContext';
import { Loader } from 'lucide-react';

const ProtectedRoute = ({ element: Component, ...rest }) => {
    const { user, loading } = useContext(UserContext);

    if (loading) {
        return (
            <div className='flex items-center justify-center py-4'>
                <Loader className='animate-spin mr-2' />
                <span>Lädt...</span>
            </div>
        );
    }

    if (!user) {
        return <Navigate to='/login' />;
    }

    return <Component {...rest} />;
};

export default ProtectedRoute;

javascript reactjs react-router react-router-dom
1个回答
0
投票

你可以这样使用它。

// App.tsx
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Dashboard from "./pages/system/Dashboard";
import User from "./pages/system/users/User";
import Layout from "./layout/DashboardLayout";
import Expence from "./pages/system/expenses/Expense";
import Product from "./pages/manager/Product";
import NotFound from "./pages/common/NotFound";
import PersistLogin from "./access/PersistLogin";
import ProtectedRoutes from "./access/ProtectedRoutes";
import { UserRole } from "./utils";

function App() {
  return (
    <BrowserRouter future={{ v7_startTransition: true }} basename="/">
      <Routes>
        {/* ======Protected routes====== */}
        <Route element={<PersistLogin />}>
          <Route
            element={
              <ProtectedRoutes
                allowedRoles={[UserRole.SYSTEM_ADMIN, UserRole.MANAGER]}
                redirectTo="/auth"
              />
            }
          >
            <Route path="/admin" element={<Layout />}>
              <Route path="dashboard" element={<Dashboard />} />
              <Route path="users" element={<User />} />
              <Route path="products" element={<Product />} />
              <Route path="expenses" element={<Expense />} />
            </Route>
          </Route>
        </Route>
        {/* ======Protected routes====== */}

        {/* ======Invalid / Catch-all route for 404====== */}
        <Route path="*" element={<NotFound />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;

有趣的事实是目前我正在探索这个路由系统🐸

这是
ProtectedRoutes.tsx
文件代码。

// ProtectedRoutes.tsx
import { TUserRole } from "@/@types";
import useAuth from "@/hooks/auth/useAuth";
import { Navigate, Outlet } from "react-router-dom";

type ProtectedRoutes = {
  allowedRoles: Array<TUserRole>;
  redirectTo: string;
};

const ProtectedRoutes = ({ allowedRoles, redirectTo }: ProtectedRoutes) => {
  const { session } = useAuth();
  // Check if user is logged in and has valid roles
  if (session?.accessToken) {
    if (allowedRoles.includes(session.user.role)) {
      return <Outlet />;
    }
    // window.location.replace("/");
    return <Navigate to="/" />;
  }
  return <Navigate to={redirectTo} />;
};

export default ProtectedRoutes;
© www.soinside.com 2019 - 2024. All rights reserved.