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

Nestjs创建用户API请求中Prisma中间件无法哈希用户密码如何解决

问题原因

你在passwordMiddleware函数内部新创建了一个独立的PrismaClient实例,给该实例绑定的中间件只会作用于这个临时实例,不会生效到Nest项目依赖注入容器中全局复用的PrismaService实例,两个实例完全隔离,因此密码哈希逻辑从未被触发。

修复方案

步骤1:修改中间件逻辑,支持传入外部Prisma实例

import { Prisma, PrismaClient } from '@prisma/client';
import * as bcrypt from 'bcrypt';

// 移除内部实例创建逻辑,改为接收外部传入的Prisma实例
export function applyPasswordMiddleware(prisma: PrismaClient) {
  prisma.$use(async (params: Prisma.MiddlewareParams, next) => {
    if (params.action === 'create' && params.model === 'User') {
      const user = params.args.data;
      const salt = bcrypt.genSaltSync(10);
      const hash = bcrypt.hashSync(user.password, salt);
      user.password = hash;
      params.args.data = user;
    }
    return next(params);
  });
}

步骤2:给项目实际使用的PrismaService实例绑定中间件,二选一即可:

方案A:在PrismaService内部绑定(更推荐,逻辑内聚)

修改你自定义的PrismaService文件:

import { Injectable, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
import { applyPasswordMiddleware } from './middleware';

@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
  constructor() {
    super();
    // 给当前服务持有的Prisma实例绑定中间件
    applyPasswordMiddleware(this);
  }

  async onModuleInit() {
    await this.$connect();
  }
}

此时可以删除main.ts中原有的passwordMiddleware()调用代码。

方案B:在main.ts中从容器获取实例绑定

修改main.ts的bootstrap逻辑:

import { Logger } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app/app.module';
import { applyPasswordMiddleware } from './app/core/prisma/middleware';
import { PrismaService } from '你的PrismaService对应路径';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const globalPrefix = 'api';
  app.setGlobalPrefix(globalPrefix);
  const port = process.env.PORT || 3333;
  
  // 从Nest的IOC容器中获取全局使用的PrismaService实例
  const prismaService = app.get(PrismaService);
  // 绑定中间件
  applyPasswordMiddleware(prismaService);
  
  await app.listen(port, () => {
    Logger.log('Listening at http://localhost:' + port + '/' + globalPrefix);
  });
}

bootstrap();

修改完成后重新启动项目,创建用户时密码就会自动被哈希处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 05:06:04