משמרים
חלק מהיחידה 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 }פתח את שדה הכותרות בסרגל הבקשה, הוסף את השורה 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
תרגלו בעצמכם: Express אונליין