محافظت از Routeها با استفاده از Gaurdها (قسمت اول)

(Protecting Routes Using Gaurds (Part 1

Vue.JS 2: محافظت از Route ها با استفاده از Gaurd ها (قسمت اول) - قسمت 85

یکی دیگر از مباحث مربوط به Routing مربوط به کنترل کردن فرآیند navigation (جابجا شدن بین صفحات) است. در برخی اوقات باید مشخص کنیم که آیا یک کاربر خاص اجازه دارد که URL خاصی را وارد کرده و از آن بازدید کند یا اینکه آیا اجازه دارد از URL خاصی خارج شود؟ مثلا ما در کامپوننت UserDetail.vue هستیم و این کامپوننت دکمه ای به نام Edit User (ویرایش کردن کاربر) دارد. آیا هر کاربری مجاز است که با کلیک روی این دکمه به صفحه ویرایش کاربران برود و بتواند کاربران ما را ویرایش کند؟ قطعا خیر! یا اصلا اگر قرار است کاربر اطلاعات خودش را ویرایش کند حتما باید چک کنیم که Login شده باشد. همچنین می خواهیم خروج کاربر از صفحه UserEdit.vue را نیز کنترل کنیم و من این کار را با یک دکمه ساده انجام می دهم (فایل UserEdit.vue):

<template>
  <div>
    <h3>Edit the User</h3>
    <p>Locale: {{ $route.query.locale }}</p>
    <p>Analytics: {{ $route.query.q }}</p>
    <hr />
    <button class="btn btn-primary">Confirm</button>
    <div style="height: 700px"></div>
    <p id="data">Some extra Data</p>
  </div>
</template>

یعنی کاربر باید در صفحه ویرایش کاربران، تغییرات را تایید (confirm) کند تا بتواند از آن صفحه خارج شود. اگر confirm نکرده باشد، از او می پرسیم که بدون تایید کردن، ویرایش ها اعمال نمی شوند. آیا مطمئن است که می خواهد خارج شود یا نه؟ بنابراین دو قسمت مجزا خواهیم داشت:

  • محافظت قبل از اینکه کاربر وارد URL خاصی شود (آیا او اجازه دارد این مسیر را باز کند؟). این مرحله را می توانیم به سه شکل مختلف اجرا کنیم.
  • محافظت پس از اینکه کاربر وارد URL خاصی شده است (آیا او اجازه ترک این مسیر را دارد؟). این مرحله به یک شکل انجام می شود.

با این حساب مجموعا چهار شکل مختلف برای استفاده از gaurd ها داریم. ما در این جلسه با دو مورد اول (وارد شدن به URL های خاص) شروع می کنیم. برای پیاده سازی روش اول باید ابتدا به فایل main.js برویم. ما router خود را در این فایل تعریف کرده و آن را به شیء سراسری Vue پاس داده ایم. حالا باید قبل از پاس دادن آن به Vue بگوییم:

router.beforeEach((to, from, next) => {
  console.log('global beforeEach');
  next();
});

new Vue({
  el: '#app',
  router,
  render: h => h(App)
})

من متد beforeEach را از router صدا زده ام. این متد همانطور که از نامش مشخص است (before یعنی «قبل از» و each یعنی «هر کدام» بنابراین می شود «قبل از هر کدام») قبل از ورود به هر صفحه اجرا خواهد شد. از آنجایی که این تابع روی تک تک صفحات اجرا خواهد شد، فقط می توانیم بررسی های کلی (نه کارهای مخصوص به هر کاموننت) را در آن انجام بدهیم. همچنین از کد بالا مشخص است که آرگومان این متد یک تابع است که سه آرگومان می گیرد:

  • to یعنی به کدام صفحه خواهیم رفت.
  • from یعنی از کدام صفحه می آییم.
  • next یک تابع callback است که اجازه می دهد دستور ادامه پیدا کند (یعنی کاربر به صفحه مورد نظر خود منتقل شود). اگر next را صدا نزنید، درخواست متوقف شده و کاربر به هیچ صفحه ای نمی تواند برود. همچنین می توانید به خود next یک path (مثلا user/edit/) پاس بدهید تا کاربر را به صفحه دیگری منتقل کند.

من درون این تابع کار خاصی نکرده ام بلکه فقط عبارت global beforeEach (یعنی beforeEach سراسری) را log کرده ام تا در کنسول مرورگر آن را ببینیم. اگر حالا به مرورگر رفته و روی هر صفحه ای کلیک کنید یا صفحه مرورگر را refresh کنید، این عبارت را در کنسول خواهید دید. البته در برنامه های واقعی شما باید کدهای واقعی خودتان را درون آن بنویسید. مثلا چک کنید که کاربر برای بازدید از سایت شما (تک تک صفحات) حتما باید login باشد و یک منطق ساده login بودن را پیاده سازی کنید. مشکل این روش اینجاست که متد ما تک تک صفحات را چک می کند اما در بسیاری از اوقات فقط باید مسیر های خاصی را چک کنیم.

فرض کنید می خواهیم فقط از UserDetail.vue محافظت کنیم. برای انجام این کار به فایل routes.js می رویم و خصوصیت beforeEnter را برای UserDetail.vue می نویسیم:

export const routes = [
    {
        path: '', name: 'Home', components: {
            default: Home,
            'header-top': Header
        }
    },
    {
        path: '/user', components: {
            default: User,
            'header-bottom': Header
        }, children: [
            { path: '', component: UserStart },
            {
                path: ':id', component: UserDetail, beforeEnter: (to, from, next) => {
                    console.log('inside route setup');
                    next();
                }
            },
            { path: ':id/edit', component: UserEdit, name: 'userEdit' }
        ]
    },
    { path: '/redirect-me', redirect: { name: 'Home' } },
    { path: '*', redirect: '/' }
];

همانطور که می بینید برای path: id که کامپوننت UserDetail را دارد، خصوصیتی به نام beforeEnter (یعنی «قبل از ورود») تعریف کرده ام که یک تابع است. شما می توانید این تابع را در یک فایل دیگر تعریف کرده و سپس مانند بقیه فایل ها در اینجا import کنید اما چون کدهای من کوتاه است تابع را در همین جا نوشته ام. باز هم می گویم که شما باید کدهای واقعی خودتان را به جای console.log قرار بدهید و این فقط یک مثال است. همچنین هیچ وقت یادتان نرود که next را صدا بزنید. حالا باید UserDetail را در مرورگر باز کنیم تا ببینیم log ما نمایش داده می شود یا خیر:

http://localhost:8080/user/1

ایجاد gaurd برای ورود به یک URL
ایجاد gaurd برای ورود به یک URL

همانطور که می بینید ابتدا global beforeEach و سپس inside route setup اجرا شده اند. در جلسه بعد در مورد روش های سوم (مربوط به ورود به URL) و چهارم (مربوط به خروج از URL) صحبت خواهیم کرد.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری آموزش رایگان Vue js از صفر تا صد توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.