Skip to Content
Authorization

Authorization with decorators

Authorization of requests can be implemented using decorators that checks if a user is authorised and passes down useful information such as current user to the controller handler via metadata that can be accessed via req.vovk.meta() method.

For an illustration, let’s create a simple authorization decorator that checks if a user is authorised and has the required permissions to access the resource. The authGuard decorator below does the following:

  • Checks if a user is authorised and returns an Unauthorised status if not.
  • Adds currentUser to the request metadata object, represented as AuthMeta interface.
  • Implements role-based access control with Permission enum.
src/decorators/authGuard.ts
import { createDecorator, HttpException, HttpStatus, type VovkRequest } from 'vovk'; import type { User } from '@/types'; export enum Permission { CAN_DO_THIS = 'CAN_DO_THIS', CAN_DO_THAT = 'CAN_DO_THAT', } // Metadata interface allows to access the currentUser in the controller export interface AuthMeta { currentUser: User; } // Create a function that identifies the user, checks permissions and updates the request metadata const checkAuth = async (req: VovkRequest, permission: Permission) => { const currentUser = identifyUserAndCheckPermissions(req, permission); if (!currentUser) { return false; } // Add currentUser to the request metadata req.vovk.meta<AuthMeta>({ currentUser }); return true; }; // Create the decorator const authGuard = createDecorator(async (req, next, permission: Permission) => { const isAuthorized = await checkAuth(req, permission); if (!isAuthorized) { throw new HttpException(HttpStatus.UNAUTHORIZED, 'Unauthorized'); } // The user is authorized, and the metadata is set; proceed to the next decorator or controller handler return next(); }); export default authGuard;

Then import the authGuard decorator and related members and apply it to the controller methods, passing it after the @get, @post, etc. decorators.

src/modules/user/UserController.ts
import { get, prefix } from 'vovk'; import { openapi } from 'vovk-openapi'; import authGuard, { Permission, type AuthMeta } from '../decorators/authGuard'; @prefix('users') export default class UserController { // ... @openapi({ summary: 'Get something', description: 'Returns something', }) @get('something') @authGuard(Permission.CAN_DO_THIS) static async getSomething(req: VovkRequest) { const { currentUser } = req.vovk.meta<AuthMeta>(); // ... } // ... }
Last updated on