الحراس
جزء من قسم 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 الموضوع على دالةٍ تلك الدالة. وعند وضعه على صنف المتحكّم، يحمي كل دالة فيه.
التحدي
سهليمكن لأي شخص الآن إنشاء المهام أو حذفها. أمّن المسارين اللذين يغيّران البيانات باستخدام مفتاح API: سرّ يرسله العميل في ترويسة الطلب. تظل القراءة متاحة للجميع.
- افتح
src/common/api-key.guard.ts. في أسلوبcanActivateضمنApiKeyGuard، اقرأ ترويسةx-api-keyفي الطلب. يوفّر لكcontext.switchToHttp().getRequest()الطلب، وتكون أسماء ترويساته دائمًا بأحرف صغيرة. - أعِد
trueفقط عندما تساوي تلك الترويسةprocess.env.API_KEY، التي يضبطها هذا الدرس علىtasks-key-123. أعِدfalseفي كل حالة أخرى، بما في ذلك عند غياب الترويسة. عندما يعيد الحارسfalse، يستجيب Nest بالرمز 403 ولا يشغّل أسلوب المسار مطلقًا. - في
src/tasks/tasks.controller.ts، استوردApiKeyGuardمن../common/api-key.guard، وUseGuardsمن@nestjs/common. أضف@UseGuards(ApiKeyGuard)إلى أسلوبcreate(POST /tasks) وإلى أسلوبremove(DELETE /tasks/:id). لا تضفه إلى الصنف؛ فهذا سيؤمّن مسارات GET أيضًا. - تظل
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;
}
}
يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس TypeScript وNestJS
تدرّب بنفسك: Playground لـ Express