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

NestJS中NestMiddleware依赖注入问题:express-session集成TypeORM报错

解决NestJS中SessionMiddleware依赖注入失败的问题

我之前也碰到过一模一样的依赖注入报错,结合你用express-session+TypeORM存储的场景,这个错误大概率是因为你的SessionMiddleware类在构造函数里声明了依赖,但Nest找不到对应的提供者。下面一步步给你理清楚怎么修:

1. 先检查你的SessionMiddleware构造函数

先看看你的中间件是不是类似这种写法(带依赖注入的类式中间件):

import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
import * as session from 'express-session';
import { TypeormStore } from 'connect-typeorm';
import { InjectRepository } from '@nestjs/typeorm';
import { SessionEntity } from './session.entity';
import { Repository } from 'typeorm';

@Injectable()
export class SessionMiddleware implements NestMiddleware {
  constructor(
    @InjectRepository(SessionEntity)
    private sessionRepository: Repository<SessionEntity>,
  ) {}

  use(req: Request, res: Response, next: NextFunction) {
    return session({
      store: new TypeormStore().connect(this.sessionRepository),
      secret: 'your-secure-secret-key',
      resave: false,
      saveUninitialized: false,
      cookie: { secure: process.env.NODE_ENV === 'production' },
    })(req, res, next);
  }
}

如果是这样,问题就出在模块注册中间件的方式上。

2. 正确注册带依赖的类式中间件

在Nest里,类式中间件如果有依赖注入,不能直接用apply()传类就完事,得确保模块能识别到这个中间件的依赖提供者:

错误的注册方式(会导致依赖找不到)

// app.module.ts
import { Module, MiddlewareConsumer } from '@nestjs/common';
import { SessionMiddleware } from './session.middleware';
import { TypeOrmModule } from '@nestjs/typeorm';
import { SessionEntity } from './session.entity';

@Module({
  imports: [TypeOrmModule.forFeature([SessionEntity])],
})
export class AppModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(SessionMiddleware).forRoutes('*'); // 直接传类会导致Nest找不到依赖
  }
}

正确的注册方式

把中间件加入模块的providers数组,让Nest的DI容器能解析它的依赖:

// app.module.ts
import { Module, MiddlewareConsumer } from '@nestjs/common';
import { SessionMiddleware } from './session.middleware';
import { TypeOrmModule } from '@nestjs/typeorm';
import { SessionEntity } from './session.entity';

@Module({
  imports: [TypeOrmModule.forFeature([SessionEntity])],
  providers: [SessionMiddleware], // 把中间件加入提供者列表
})
export class AppModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(SessionMiddleware).forRoutes('*');
  }
}

3. 确保TypeORM配置和实体正确

另外要确认两个关键点:

  • 根模块已经导入了TypeOrmModule.forRoot(),完成数据库连接配置
  • SessionEntity的字段完全符合connect-typeorm的要求,比如:
// session.entity.ts
import { Entity, Column, PrimaryColumn } from 'typeorm';

@Entity()
export class SessionEntity {
  @PrimaryColumn()
  id: string;

  @Column()
  expiresAt: number;

  @Column('text')
  data: string;
}

4. 备选方案:用函数式中间件绕开DI问题

如果类式中间件的DI实在折腾不清楚,也可以换成函数式中间件,手动获取Repository:

// session.middleware.ts
import { Request, Response, NextFunction } from 'express';
import * as session from 'express-session';
import { TypeormStore } from 'connect-typeorm';
import { getRepository } from 'typeorm';
import { SessionEntity } from './session.entity';

export function sessionMiddleware(req: Request, res: Response, next: NextFunction) {
  const sessionRepository = getRepository(SessionEntity);
  return session({
    store: new TypeormStore().connect(sessionRepository),
    secret: 'your-secure-secret-key',
    resave: false,
    saveUninitialized: false,
    cookie: { secure: process.env.NODE_ENV === 'production' },
  })(req, res, next);
}

然后在模块里注册:

// app.module.ts
configure(consumer: MiddlewareConsumer) {
  consumer.apply(sessionMiddleware).forRoutes('*');
}

这种方式不需要依赖注入,适合快速解决问题,但类式中间件的可测试性会更好一些。

最后检查启动顺序

如果还是不行,可能是TypeORM连接还没建立就初始化了session中间件。可以给中间件加上OnModuleInit钩子,确保数据库连接完成后再初始化session:

@Injectable()
export class SessionMiddleware implements NestMiddleware, OnModuleInit {
  private sessionMiddleware: any;

  constructor(
    @InjectRepository(SessionEntity)
    private sessionRepository: Repository<SessionEntity>,
  ) {}

  async onModuleInit() {
    await this.sessionRepository.manager.connection.connect();
    this.sessionMiddleware = session({
      store: new TypeormStore().connect(this.sessionRepository),
      // 其他session配置
    });
  }

  use(req: Request, res: Response, next: NextFunction) {
    this.sessionMiddleware(req, res, next);
  }
}

按上面的步骤调整后,应该就能解决依赖注入失败的问题,让Express正常启动了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:31:47