Menu
CoddyTech

الحراس

جزء من قسم TypeScript وNestJS في رحلة Node.js على Coddy. الدرس 18 من 24.

يمكن لأي شخص إنشاء المهام أو حذفها. يحدد الحارس ما إذا كان يُسمح للطلب بالوصول إلى معالجه: يستدعي Nest الدالة canActivate، وعندما تُرجع false، يرد Nest بالرمز 403 Forbidden من دون تشغيل الدالة.

@Injectable()
export class OpenHoursGuard implements CanActivate {
    canActivate(context: ExecutionContext): boolean {
        const hour = new Date().getHours();
        return hour >= 9 && hour < 17;
    }
}

@Post()
@UseGuards(OpenHoursGuard)
book() {}

تُوفّر context.switchToHttp().getRequest() الطلب؛ ويخزّن Node أسماء ترويساته بأحرف صغيرة، لذا اقرأ request.headers['x-api-key']. يحمي @UseGuards الموضوع على دالةٍ تلك الدالة. وعند وضعه على صنف المتحكّم، يحمي كل دالة فيه.

challenge icon

التحدي

سهل

يمكن لأي شخص الآن إنشاء المهام أو حذفها. أمّن المسارين اللذين يغيّران البيانات باستخدام مفتاح API: سرّ يرسله العميل في ترويسة الطلب. تظل القراءة متاحة للجميع.

  1. افتح src/common/api-key.guard.ts. في أسلوب canActivate ضمن ApiKeyGuard، اقرأ ترويسة x-api-key في الطلب. يوفّر لك context.switchToHttp().getRequest() الطلب، وتكون أسماء ترويساته دائمًا بأحرف صغيرة.
  2. أعِد true فقط عندما تساوي تلك الترويسة process.env.API_KEY، التي يضبطها هذا الدرس على tasks-key-123. أعِد false في كل حالة أخرى، بما في ذلك عند غياب الترويسة. عندما يعيد الحارس false، يستجيب Nest بالرمز 403 ولا يشغّل أسلوب المسار مطلقًا.
  3. في src/tasks/tasks.controller.ts، استورد ApiKeyGuard من ../common/api-key.guard، وUseGuards من @nestjs/common. أضف @UseGuards(ApiKeyGuard) إلى أسلوب create (POST /tasks) وإلى أسلوب remove (DELETE /tasks/:id). لا تضفه إلى الصنف؛ فهذا سيؤمّن مسارات GET أيضًا.
  4. تظل GET /tasks وGET /tasks/:id وGET /stats تعمل دون مفتاح.

جرّب ذلك: أرسل POST يتضمن { "title": "Buy milk" } إلى /tasks دون ترويسة. ستحصل على 403:

{ "message": "Forbidden resource", "error": "Forbidden", "statusCode": 403 }

افتح حقل Headers في شريط الطلب، وأضف السطر x-api-key: tasks-key-123، ثم أرسل POST مجددًا: ستحصل على 201 والمهمة الجديدة. باستخدام x-api-key: guess ستحصل على 403. يحتاج DELETE /tasks/4 إلى المفتاح أيضًا: 403 من دونه، و204 معه. يعمل GET /tasks دون أي ترويسة.

جرّب بنفسك

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common';

@Injectable()
export class ApiKeyGuard implements CanActivate {
    canActivate(context: ExecutionContext): boolean {
        // اسمح بمرور الطلب فقط عندما تكون ترويسة x-api-key الخاصة به
        // مساويةً لـ process.env.API_KEY.
        return true;
    }
}
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس TypeScript وNestJS

تدرّب بنفسك: Playground لـ Express