NestJS 中间件与拦截器:请求处理流程详解

在上一篇文章中,我们介绍了 NestJS 的认证与授权实现。本文将深入探讨 NestJS 的请求处理流程,包括中间件、拦截器、管道和异常过滤器的使用。

请求生命周期

在 NestJS 中,请求处理流程按以下顺序执行:

  1. 中间件(Middleware)
  2. 守卫(Guards)
  3. 拦截器(Interceptors)- 前置处理
  4. 管道(Pipes)
  5. 控制器(Controller)
  6. 服务(Service)
  7. 拦截器(Interceptors)- 后置处理
  8. 异常过滤器(Exception Filters)

中间件实现

1. 函数式中间件

// src/common/middleware/logger.middleware.ts
import { Request, Response, NextFunction } from 'express';

export function loggerMiddleware(req: Request, res: Response, next: NextFunction) {
  const { method, originalUrl, ip } = req;
  const userAgent = req.get('user-agent') || '';

  console.log(`[${method}] ${originalUrl} - ${ip} - ${userAgent}`);

  // 记录请求开始时间
  const start = Date.now();

  // 响应结束后记录耗时
  res.on('finish', () => {
    const duration = Date.now() - start;
    console.log(`[${method}] ${originalUrl} - ${res.statusCode} - ${duration}ms`);
  });

  next();
}

2. 类中间件

// src/common/middleware/auth.middleware.ts
import { Injectable, NestMiddleware, UnauthorizedException } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
import { JwtService } from '@nestjs/jwt';

@Injectable()
export class AuthMiddleware implements NestMiddleware {
  constructor(private jwtService: JwtService) {}

  async use(req: Request, res: Response, next: NextFunction) {
    const authHeader = req.headers.authorization;

    if (!authHeader) {
      next();
      return;
    }

    try {
      const token = authHeader.split(' ')[1];
      const payload = await this.jwtService.verifyAsync(token);
      req['user'] = payload;
      next();
    } catch (error) {
      throw new UnauthorizedException('Invalid token');
    }
  }
}

3. 全局中间件

// src/app.module.ts
import { Module, NestModule, MiddlewareConsumer, RequestMethod } from '@nestjs/common';
import { AuthMiddleware } from './common/middleware/auth.middleware';
import { loggerMiddleware } from './common/middleware/logger.middleware';

@Module({
  // ... 其他配置
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(loggerMiddleware, AuthMiddleware)
      .exclude(
        { path: 'auth/login', method: RequestMethod.POST },
        { path: 'auth/register', method: RequestMethod.POST },
      )
      .forRoutes('*');
  }
}

拦截器实现

1. 响应转换拦截器


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值