You need to enable JavaScript to run this app. NestJS使用useGlobalGuards、useGlobalPipes时如何排除指定端点?
优惠活动
大模型
产品
解决方案
定价
更多

NestJS使用useGlobalGuards、useGlobalPipes时如何排除指定端点?

全局守卫/管道排除指定接口解决方案

可以实现该需求,核心思路是通过NestJS原生的元数据机制给需要排除的接口打标记,在全局守卫/管道中读取标记后跳过对应逻辑,该方案同时适配useGlobalGuards和useGlobalPipes场景。

全局守卫(useGlobalGuards)实现步骤

步骤1:定义公共接口标记装饰器

// src/common/decorators/public.decorator.ts
import { SetMetadata } from '@nestjs/common';

export const IS_PUBLIC_KEY = 'isPublic';
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);

步骤2:改造AuthGuard增加公共接口判断逻辑

注入Reflector工具类读取元数据,优先放行标记为公共的接口:

// src/common/guards/auth.guard.ts
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { IS_PUBLIC_KEY } from '../decorators/public.decorator';

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(private reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean | Promise<boolean> {
    // 同时支持接口级别和控制器级别的公共标记
    const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    // 公共接口直接跳过校验
    if (isPublic) return true;

    // 原有令牌校验逻辑保持不变
    const request = context.switchToHttp().getRequest();
    // ... 你的令牌校验逻辑
  }
}

步骤3:给需要跳过校验的接口添加装饰器

直接在控制器或者单个接口上添加@Public()即可:

// src/user/user.controller.ts
import { Public } from '../common/decorators/public.decorator';
import { Post, Body, Controller } from '@nestjs/common';

@Controller('user')
export class UserController {
  // 单个接口标记为公共
  @Public()
  @Post('register')
  register(@Body() registerDto: any) {
    // 注册逻辑
  }

  // 其余接口仍走全局校验
  @Post('profile')
  getProfile() {
    return {}
  }
}

全局管道(useGlobalPipes)适配方案

同样可以通过自定义元数据实现排除逻辑,步骤如下:

  1. 自定义@SkipValidation装饰器标记不需要校验的接口
  2. 继承官方ValidationPipe实现自定义管道,读取元数据后跳过对应校验
    示例代码:
// 定义跳过校验装饰器
import { SetMetadata } from '@nestjs/common';
export const SKIP_VALIDATION_KEY = 'skipValidation';
export const SkipValidation = () => SetMetadata(SKIP_VALIDATION_KEY, true);

// 自定义全局校验管道
import { ValidationPipe, ArgumentMetadata, Injectable } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

@Injectable()
export class CustomValidationPipe extends ValidationPipe {
  constructor(private reflector: Reflector) {
    super({ transform: true });
  }

  transform(value: any, metadata: ArgumentMetadata) {
    const isSkip = this.reflector.get(SKIP_VALIDATION_KEY, metadata.metatype);
    if (isSkip) return value;
    return super.transform(value, metadata);
  }
}

内容的提问来源于stack exchange,提问作者Lucas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 09:39:04