تنظیم مسیرهای حفاظت شده در اپلیکیشن ری اکت — از صفر تا صد

۱۵۲ بازدید
آخرین به‌روزرسانی: ۰۳ مهر ۱۴۰۲
زمان مطالعه: ۴ دقیقه
تنظیم مسیرهای حفاظت شده در اپلیکیشن ری اکت — از صفر تا صد

در اغلب موارد وقتی می‌خواهیم یک وب اپلیکیشن بسازیم باید نوعی مسیریابی داشته باشیم که احراز هویت را اجرا کند. در این موارد می‌خواهیم دسترسی کاربر را به برخی صفحه‌های خاص محدود سازیم و یا کل اپلیکیشن در پشت یک صفحه لاگین قرار گیرد. در این مقاله به توضیح روش تنظیم مسیرهای حفاظت شده در اپلیکیشن ری‌اکت می‌پردازیم.

ری‌اکت روتر روشی عالی برای تنظیم مسیریابی است، اما متأسفانه گزینه‌ای برای حفاظت از مسیرها جهت جلوگیری از دسترسی افراد ارائه نمی‌کند. خوشبختانه راه‌حل این مشکل ساده و کاملاً سرراست است. در ادامه این مقاله با روش حل این مشکل آشنا می‌شویم. کار را از ابتدا و از اسکریپت create-react-app آغاز می‌کنیم و تنها موارد کاملاً ضروری را می‌گنجانیم تا بتوانید این راهنما را پیگیری کنید.

تنظیم اولیه موارد مختلف

پس از آن که پروژه را با اسکریپت create-react-app بوت‌استرپ کردیم، react-router-dom را برای مسیریابی نصب می‌کنیم. در این پروژه به هیچ وابستگی دیگری نیاز نداریم. بدون ایجاد هیچ گونه تغییری در create-react-app وضعیت کنونی فایل package.json به صورت زیر است:

1{
2  "name": "auth",
3  "version": "0.1.0",
4  "private": true,
5  "dependencies": {
6    "@testing-library/jest-dom": "^4.2.4",
7    "@testing-library/react": "^9.4.0",
8    "@testing-library/user-event": "^7.2.1",
9    "react": "^16.12.0",
10    "react-dom": "^16.12.0",
11+   "react-router-dom": "^5.1.2",
12    "react-scripts": "3.3.1"
13  },
14  "scripts": {
15    "start": "react-scripts start",
16    "build": "react-scripts build",
17    "test": "react-scripts test",
18    "eject": "react-scripts eject"
19  },
20  "eslintConfig": {
21    "extends": "react-app"
22  },
23  "browserslist": {
24    "production": [
25      ">0.2%",
26      "not dead",
27      "not op_mini all"
28    ],
29    "development": [
30      "last 1 chrome version",
31      "last 1 firefox version",
32      "last 1 safari version"
33    ]
34  }
35}

ویرایش فایل ایندکس

برای طراحی لایه حفاظتی، یک کامپوننت می‌سازیم که درخواست‌های ورودی را مدیریت کند. به این منظور یک کامپوننت Route قدیمی ساده در ری‌اکت اضافه می‌کنیم. از آن صرفاً برای یک مسیر عمومی که داریم یعنی صفحه لاگین استفاده می‌کنیم. همچنین می‌خواهیم یک کامپوننت سفارشی داشته باشیم که مسیرهای خصوصی را مدیریت کند و نام آن را protectedRoute می‌گذاریم.

هدف این کامپوننت بسیار ساده است: اگر کاربر احراز هویت شده باشد، کامپوننت ارسالی را رندر می‌کند. در غیر این صورت او را به صفحه لاگین هدایت می‌کند:

1import React from 'react';
2import ReactDOM from 'react-dom';
3import { Route, BrowserRouter, Switch } from 'react-router-dom';
4import './index.css';
5import Login from './Login';
6import Dashboard from './Dashboard';
7import Settings from './Settings';
8import ProtectedRoute from './ProtectedRoute';
9import * as serviceWorker from './serviceWorker';
10
11ReactDOM.render((
12    <BrowserRouter>
13        <Switch>
14            <Route path="/login" component={Login} />
15            <ProtectedRoute exact={true} path="/" component={Dashboard} />
16            <ProtectedRoute path="/settings" component={Settings} />
17             <ProtectedRoute component={Dashboard} />
18        </Switch>
19    </BrowserRouter>
20), document.getElementById('root'));
21
22// If you want your app to work offline and load faster, you can change
23// unregister() to register() below. Note this comes with some pitfalls.
24// Learn more about service workers: https://bit.ly/CRA-PWA
25serviceWorker.unregister();

چنان که می‌بینید در فایل Index اقدام به ایمپورت Route ،BrowserRoute و Switch از react-router-dom کرده‌ایم. همچنین برخی کامپوننت‌ها ساخته‌ایم تا بتوانیم مسیریابی خود را تست کنیم. ProtectedRoute به روش زیر عمل می‌کند:

  • یک prop به نام component می‌گیرد که تنها prop است که باید رندر کند.
  • همچنین یک مسیر می‌گیرد و از این رو می‌داند که کامپوننت روی کدام URL رندر خواهد شد.

در کد فوق دو بار کامپوننت Dashboard را تعریف کرده‌ایم. دلیل این امر آن است که می‌خواهیم در صورت عدم تعیین هیچ path داشبورد را بارگذاری کنیم. این کار در خط 15 مدیریت می‌شود. همچنین می‌خواهیم در صورتی که کاربر یک URL نامعتبر وارد کرده باشد، داشبورد بارگذاری شود. با حذف خصوصیت path در خط 17 به React Router اعلام می‌کنیم که به کامپوننت ارائه شده fallback کند.

در بخش بعدی با طرز کار داخلی کامپوننت ProtectedRoute آشنا می‌شویم.

ایجاد مسیرهای خصوصی

شاید بپرسید درون کامپوننت سفارشی که ایمپورت کردیم چه چیز قرار دارد؟ در واقع این کامپوننت ساده‌ای است و تنها یک تابع را رندر می‌کند:

1import React from 'react'
2import { Redirect } from 'react-router-dom'
3
4class ProtectedRoute extends React.Component {
5
6    render() {
7        const Component = this.props.component;
8        const isAuthenticated = ???;
9       
10        return isAuthenticated ? (
11            <Component />
12        ) : (
13            <Redirect to={{ pathname: '/login' }} />
14        );
15    }
16}
17
18export default ProtectedRoute;

ما کامپوننت را از props می‌گیریم و آن را در صورتی بازگشت می‌دهیم که کاربر احراز هویت شده باشد. همچنین از Redirect ارائه شده از سوی react-router-dom استفاده می‌کنیم. اگر مشخص شود که isAuthenticated نادرست است، کاربر را به صفحه لاگین هدایت می‌کنیم. اینک شاید بپرسید چطور باید تصمیم بگیریم که آیا کاربر احراز هویت شده است یا نه؟ چه مقداری باید به isAuthenticated انتساب یابد؟

احراز هویت کاربران

در این بخش آخرین گام یعنی احراز هویت کاربران را بررسی می‌کنیم. این کار به روش‌های مختلفی می‌تواند انجام یابد و بسته به پیاده‌سازی‌های مختلف می‌تواند متفاوت باشد. می‌توان از کوکی‌ها یا localStorage و یا ترکیبی از هر دو یا هر چیز دیگری استفاده کرد. در هر صورت باید برخی اطلاعات را در مورد کاربر در سمت کلاینت ذخیره کنیم تا بدانیم که وی لاگین کرده است.

1render() {
2    const Component = this.props.component;
3    const isAuthenticated = localStorage.getItem('token');
4  
5    return isAuthenticated ? (
6        <Component />
7    ) : (
8        <Redirect to={{ pathname: '/login' }} />
9    );
10}

برای جلوگیری از جعل هویت، این اطلاعات باید نشان‌دهنده وجود یا عدم توکن باشند که در سمت سرور نیز تأیید می‌شوند. بدین ترتیب مطمئن می‌شویم که کاربر نمی‌تواند صرفاً بر مبنای وجود کلید توکن لاگین کند. در واقع این مقدار توکن است که در عمل مهم است.

مسیرهای حفاظت شده

همان طور که در تصویر فوق می‌بینید، اگر صفحه را رفرش کنیم، ما را به صفحه لاگین می‌برد. اگر تلاش کنیم به مسیر دیگری که محدود شده است دسترسی پیدا کنیم، به صفحه لاگین هدایت می‌شویم. اگر یک توکن تنظیم کنیم که مقدار آن فعلاً اهمیتی ندارد می‌توانیم به این صفحه‌ها دسترسی داشته باشیم. همچنین توجه داشته باشید که اگر در زمانی که لاگین کرده‌ایم، تلاش کنیم به صفحه‌ای که وجود ندارد دسترسی پیدا کنیم به صفحه داشبورد هدایت می‌شویم. به محض این که storage را پاک کنیم دسترسی ما از بین می‌رود.

سخن پایانی

با این که کد ری‌اکت obfuscate می‌شود، اما طرز کار اپلیکیشن می‌تواند مهندسی معکوس شود. به همین دلیل است که همه موارد مرتبط با احراز هویت و احراز دسترسی باید در پیاده‌سازی سمت سرور نیز پشتیبانی شود. در این مقاله با روش تنظیم مسیرهای حفاظت شده در اپلیکیشن‌های ری‌اکت آشنا شدیم.

اگر این مطلب برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

==

بر اساس رای ۳ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
javascript-in-plain-english
نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *