You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NestJS的Services中获取中间件挂载的req.user对象

方案1:使用请求作用域注入Request对象

NestJS内置了REQUEST注入令牌,配合请求作用域可以直接在Service中注入当前请求对象,无需从Controller层传递:

  • 首先给你的Service设置请求作用域,注入REQUEST令牌:
import { Injectable, Scope, Inject } from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
import { Request } from 'express';

@Injectable({ scope: Scope.REQUEST })
export class YourBusinessService {
  constructor(@Inject(REQUEST) private req: Request) {}

  someBusinessMethod() {
    // 直接获取用户ID
    const userId = this.req.user.id;
    // 后续业务逻辑
  }
}
  • 注意事项:请求作用域的Provider会随每次请求创建、销毁,不能直接注入到单例Provider中,否则会导致父Provider也被降级为请求作用域,高并发场景下会有一定性能损耗。
方案2:使用AsyncLocalStorage存储请求上下文

该方案不会修改Service的单例属性,无作用域污染问题,性能更优,是更推荐的生产级方案:

  1. 先创建全局共享的AsyncLocalStorage实例
// src/common/async-local-storage.ts
import { AsyncLocalStorage } from 'async_hooks';
// 泛型可根据你的User类型自定义
export const als = new AsyncLocalStorage<{ user: any }>();
  1. 修改你的身份认证中间件,在请求链路中注入上下文
import { als } from 'src/common/async-local-storage';

@Injectable()
export class AuthenticationMiddleware implements NestMiddleware {
  async use(req: any, res: any, next: () => void) {        
    const authHeaders = req.headers.authorization;
    if (authHeaders) {
      // 原有校验逻辑,获取user对象
      req.user = user;
      // 将用户信息存入AsyncLocalStorage,再执行后续请求链路
      als.run({ user }, next);
    } else {
      throw new UnauthorizedException();
    }
  }
}
  1. 任意Service中直接读取当前用户信息
import { als } from 'src/common/async-local-storage';
import { UnauthorizedException } from '@nestjs/common';

@Injectable()
export class YourBusinessService {
  someBusinessMethod() {
    const store = als.getStore();
    if (!store?.user) {
      throw new UnauthorizedException('用户身份未校验');
    }
    const userId = store.user.id;
    // 后续业务逻辑
  }
}
  • 注意事项:正常HTTP请求链路的异步操作都能正确继承上下文,如果你手动创建了脱离请求链路的异步任务(如未绑定上下文的setTimeout、独立队列任务),需要单独处理上下文传递。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 23:45:01