我在我的 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;
// 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;