ایجاد مسیرهای محافظتشده با react-router-dom
این راهنما به شما نشان میدهد که چگونه با استفاده از react-router-dom و ذخیرهسازی اطلاعات در localStorage، مسیرهای محافظتشدهای ایجاد کنید که تنها کاربران لاگینشده میتوانند به آنها دسترسی داشته باشند. پس از ورود به سیستم، کاربر به صفحه داشبورد هدایت میشود. تمام عملکردها در ContextApi پیادهسازی شدهاند.
در اینجا دو روش برای ایجاد مسیرهای محافظتشده با react-router-dom ارائه میشود، یکی برای نسخه 6 و دیگری برای نسخههای قدیمیتر (5 و قبلتر).
روش اول (برای react-router-dom v6):
این روش از کامپوننتهای Outlet و Navigate استفاده میکند و رویکردی تمیز و سازمانیافته ارائه میدهد. ابتدا، یک کامپوننت PrivateRoutes ایجاد میکنیم که وضعیت احراز هویت کاربر را بررسی میکند:
import { Navigate, Outlet, useLocation } from 'react-router-dom';
import { useContext } from 'react';
import { globalC } from './context';
const PrivateRoutes = () => {
const location = useLocation();
const { authLogin } = useContext(globalC);
if (authLogin === undefined) {
return null; // یا نمایش یک نشانگر بارگذاری
}
return authLogin
? <Outlet />
: <Navigate to="/login" replace state={{ from: location }} />;
};
این کامپوننت authLogin را از ContextApi دریافت میکند. اگر کاربر لاگین کرده باشد (authLogin true باشد)، Outlet اجازه میدهد تا کامپوننتهای فرزند (مسیرهای محافظتشده) رندر شوند. در غیر این صورت، کاربر به صفحه لاگین (/login) هدایت میشود و آدرس قبلی در state ذخیره میشود تا پس از لاگین به همان صفحه برگردد.
سپس، مسیرهای برنامه را با استفاده از Routes و Route تعریف میکنیم:
<BrowserRouter>
<Routes>
<Route path="/" element={<PrivateRoutes />} >
<Route path="dashboard" element={<Dashboard />} />
<Route path="about" element={<About />} />
</Route>
<Route path="/login" element={<Login />} />
<Route path="*" element={<PageNotFound />} />
</Routes>
</BrowserRouter>
در این مثال، /dashboard و /about مسیرهای محافظتشده هستند و PrivateRoutes حفاظت از آنها را بر عهده دارد. /login مسیر عمومی است و * برای مسیرهای ناموجود استفاده میشود.
کامپوننت Login باید پس از موفقیتآمیز بودن لاگین، کاربر را به صفحه قبلی (location.state.from) هدایت کند:
import { useLocation, useNavigate } from 'react-router-dom';
// ... بقیه کدها
useEffect(() => {
if (authLogin) {
const { from } = location.state || { from: { pathname: "/" } };
navigate(from, { replace: true });
}
}, [authLogin, location, navigate]);
// ... بقیه کدها
روش دوم (برای react-router-dom v5 و قبلتر):
برای نسخههای قدیمیتر react-router-dom، میتوان از یک کامپوننت سفارشی به نام PrivateRoute استفاده کرد:
import { Route, Redirect, useLocation } from 'react-router-dom';
import { useContext } from 'react';
import { globalC } from './context';
const PrivateRoute = ({ component: Component, ...rest }) => {
const location = useLocation();
const { authLogin } = useContext(globalC);
if (authLogin === undefined) {
return null; // یا نمایش یک نشانگر بارگذاری
}
return authLogin ? (
<Route {...rest} component={Component} />
) : (
<Redirect
to={{
pathname: "/login",
state: { from: location }
}}
/>
);
};
سپس در تعریف مسیرها، PrivateRoute را به جای Route استفاده میکنیم:
function Routes() {
return (
<BrowserRouter>
<Switch>
<PrivateRoute path="/dashboard" component={Dashboard} />
<PrivateRoute path="/About" component={About} />
<Route path="/login" component={Login} />
<Route component={PageNotFound} />
</Switch>
</BrowserRouter>
);
}
به یاد داشته باشید که در کامپوننت Login، پس از لاگین، از history.replace(from) برای هدایت کاربر به مسیر قبلی استفاده شود.
در هر دو روش، اطمینان حاصل کنید که authLogin در ContextApi به درستی مدیریت میشود و اطلاعات لاگین در localStorage به طور ایمن ذخیره میشوند. همچنین، در نظر داشته باشید که استفاده از localStorage برای ذخیرهسازی اطلاعات حساس امنیتی نیست و برای کاربردهای مهم بهتر است از روشهای امنتر مانند sessionStorage یا استفاده از کوکیها با تنظیمات امنیتی مناسب استفاده شود.