آشنایی با Gaurd ها + مدیریت صفحات 404

22 بهمن 1399
آشنایی با Gaurd ها + مدیریت صفحات 404

آشنایی با Gaurd ها

حالا که با مبحث Redirect کردن کاربران آشنا شدیم، دوست دارم در مورد موضوعی بحث کنم که تا حدی به redirect کردن هم مربوط می شود؛ Gaurd ها (به معنی «نگهبان»). اگر با فریم ورک های دیگر دنیای وب کار کرده باشید احتمالا با Gaurd ها آشنا هستید (البته ممکن است نام های متفاوتی مثل gate یا غیره داشته باشند). معمولا زمانی از Gaurd ها استفاده می شود که نمی دانیم کاربر احراز هویت (authenticate) شده است یا خیر و از طرفی برخی از قسمت ها و Route های برنامه ی شما فقط در دسترس افراد authenticate شده هستند (به طور مثال قسمت ویرایش پروفایل کاربری و...).

البته مسئله اینجاست که در react-router باید به شکل جدیدی به مفهوم gaurd ها نگاه کنید. به کدهای فایل Blog.js نگاهی بیندازید:

<Switch>
    <Route path="/new-post" component={NewPost} />
    <Route path="/posts" component={Posts} />
    <Redirect from="/" to="/posts" />
    {/* <Route path="/" component={Posts} /> */}
</Switch>

از آنجایی که در این کدها تنها کامپوننت های خاصی (مثل NewPost و Posts) را render می کنیم برای جلوگیری از دسترسی به آن ها می توانیم بارگذاری شان را مشروط به شرط خاصی قرار دهیم. به طور مثال در همین فایل Blog.js یک state به صورت زیر تعریف می کنیم:

     state = {
        auth: false
    }

حالا می توانیم بر اساس این شرط کامپوننت مورد نظرمان را بارگذاری کنیم. مثلا:

<Switch>
    {this.state.auth ? <Route path="/new-post" component={NewPost} /> : null}
    <Route path="/posts" component={Posts} />
    <Redirect from="/" to="/posts" />
    {/* <Route path="/" component={Posts} /> */}
</Switch>

بدین شکل اگر کاربر احراز هویت نشده باشد (مقدار state.auth برابر true نباشد) به هیچ عنوان نمی تواند به مسیر new-post و کامپوننت آن دسترسی داشته باشد. حالا اگر همین کد را ذخیره کنیم و به مرورگر برویم شاهد صحت این موضوع هستیم. ما می توانیم روی لینک new-post کلیک کنیم اما به جای مشاهده ی کامپوننت NewPost به صفحه ی اصلی Posts منتقل (redirect) می شویم. این کد یک gaurd در react-router است که کاملا با gaurd های فریم ورک هایی مثل فریم ورک آنگولار متفاوت است.

توجه داشته باشید که من هیچ سیستم احراز هویتی در این پروژه پیاده سازی نکرده ام بنابراین این state فقط نمادی از این حالت است. یعنی شما باید خودتان در پروژه های واقعی تان مکانیسمی برای احراز هویت ایجاد کنید (مثلا به صورت یک کامپوننت جداگانه که فرآیند login و logout را کنترل کند) سپس این مکانیسم باید در نهایت مقدار this.state.auth را برای هر کاربر تغییر دهد. تغییر ایجاد شده توسط این مکانیسم باعث آزاد شدن آدرس هایی مثل new-post/ در برنامه ی ما می شوند و فعلا قرار بر این است که چنین مکانیسمی را در ذهن خود تصور کنیم. در اینجا مهم درک کلیت موضوع و مکانیسم بستن صفحات است نه جزئیات راه اندازی آن ها (در فصل های بعدی در مورد داده های کاربران و ... صحبت خواهیم کرد.

همچنین روش دیگر این است که به صفحه ی محافظت شده (در اینجا NewPost.js) برویم و در componentDidMount وضعیت احراز هویت را بررسی کنیم. در صورتی که کاربر احراز هویت نشده باشد می توانیم او را به صفحه ی دیگری انتقال دهیم. مثال:

componentDidMount() {
    // if unauth => this.props.history.replace('/posts');
    console.log(this.props);
}

من این مورد را به صورت کامنت درون این فایل اضافه کرده ام تا با موارد دیگر برنامه تداخل نداشته باشد.

سوال بعدی که مطرح می شود این است که اگر بخواهیم به Route یا مسیری برویم که وجود نداشته باشد چه اتفاقی می افتد؟ به طور مثال الان مسیر new-post/ برای ما تعریف نشده است چرا که هیچ سیستم احراز هویتی نداشته و بر اساس کدهایی که نوشتیم چنین route ای نیز برایمان وجود ندارد.

خطاهای 404 در ری اکت

بله، در حال حاضر مسیر new-post/ برای ما تعریف نشده است و اگر آدرس آن را در مرورگر تایپ کرده یا روی لینک New Post کلیک کنیم، سریعا به صفحه ی پست ها redirect خواهیم شد. این روش یکی از روش های برخورد با خطاهای 404 (وجود نداشتن آدرس یا صفحه ی خاص) است اما روش دیگری نیز برای مدیریت آن ها وجود دارد. ابتدا دستور <Redirect> را در Blog.js کامنت می کنم تا خطاهای 404 در ری اکت را redirect نکند:

{/* <Redirect from="/" to="/posts" /> */}

حالا می توانیم یک <Route> جدید را به این قسمت اضافه کنیم اما قسمت path را برای آن ننویسیم! بدین صورت تمام درخواست های 404 به آن منتقل می شوند. حالا می توان به این <Route> یک کامپوننت یا کدی محدود برای render شدن داد. مثال:

<Switch>
    {this.state.auth ? <Route path="/new-post" component={NewPost} /> : null}
    <Route path="/posts" component={Posts} />
    <Route render={() => <h1>Not Found</h1>} />
    {/* <Redirect from="/" to="/posts" /> */}
    {/* <Route path="/" component={Posts} /> */}
</Switch>

من در اینجا فقط یک <h1> را return کرده ام اما شما می توانید یک کامپوننت جداگانه برای مدیریت درخواست های 404 در ری اکت بسازید و آن را به صورت یک کامپوننت نمایش دهید. توجه داشته باشید که این نوع از <Route> باید همیشه آخرین <Route> شما باشد تا با Route های دیگری تداخل نداشته و مانع بارگذاری کامپوننت های دیگر نشود.

همچنین از آنجایی که دستور <Redirect> را کامنت کردیم، <Route> جدید مسئول مدیریت درخواست های 404 است بنابراین آدرس http://localhost:3000 که قبلا ما را به posts/ منتقل می کرد حالا فقط Not Found را نمایش می دهد، دقیقا مانند آدرس new-post/. در چند قسمت بعد در مورد lazy loading مسیر ها (Route ها) صحبت خواهیم کرد و سپس این فصل را به پایان می رسانیم.

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

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