Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nest.js pass variable from middleware to controller

I couldn't find a clear way of passing variables from a middleware to a constructure in Nest.js. I'm validating a JWT inside my AuthMiddleware and I want to make this token accessible to the controllers.
Below is just an extract of my middleware to provide a code sample. I want to make the token accessible inside of my Controllers.

import { Request, Response, NextFunction } from 'express';
// other imports

@Injectable()
export class AuthMiddleware implements NestMiddleware {
  async use(req: Request, res: Response, next: NextFunction) {
    const authHeader = req.header('authorization');

    if (!authHeader) {
      throw new HttpException('No auth token', HttpStatus.UNAUTHORIZED);
    }

    const bearerToken: string[] = authHeader.split(' ');
    const token: string = bearerToken[1];

    res.locals.token = token;
  }
}

I already tried to make the token accessible by changing the res.locals variable but the response object is still empty in my controller. This is my controller in which I want to access the token of the middleware:

@Controller('did')
export default class DidController {
  constructor(private readonly didService: DidService) {}

  @Get('verify')
  async verifyDid(@Response() res): Promise<string> {
    console.log(res)
    // {}
    return res;
  }
like image 909
JonasLevin Avatar asked Aug 30 '26 16:08

JonasLevin


1 Answers

Better approach would be to create a parameter decorator and use it to inject token dependency in controller without modifying code of the controller to unnecessarily use Request/Response

AuthMiddleware

import { Request, Response, NextFunction } from 'express';
// other imports

@Injectable()
export class AuthMiddleware implements NestMiddleware {
  async use(req /*: Request */, res: Response, next: NextFunction) {
    const authHeader = req.header('authorization');

    if (!authHeader) {
      throw new HttpException('No auth token', HttpStatus.UNAUTHORIZED);
    }

    const bearerToken: string[] = authHeader.split(' ');
    const token: string = bearerToken[1];

    req.token  = token; // request type is commented out otherwise typescript won't allow setting this

    next();
  }
}

Parameter decorator (./token.decorator.ts):

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

export const TOKEN = createParamDecorator(
  (_data: unknown, ctx: ExecutionContext) => {
    const request = ctx.switchToHttp().getRequest();
    return request.token; // extract token from request
  },
);

Controller:

import { Controller, Get, Response } from '@nestjs/common';
import { TOKEN } from './token.decorator';

@Controller()
export class AppController {
  constructor() {}


  @Get('verify')
  async verifyDid(@TOKEN() token): Promise<string> {
    console.log(token);
    return 'whateverYouWant';
  }
}
like image 184
Abdul Rauf Avatar answered Sep 01 '26 08:09

Abdul Rauf



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!