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
相关产品推荐
相关产品推荐

