无法在创建用户 API 请求时使用 Nestjs 中的 Prisma 中间件对用户密码进行哈希处理
Cannot hash the user's password with Prisma middleware in Nestjs on create User API request
我想使用 Prisma 中间件在创建 API 时对用户密码进行哈希处理,但它不起作用。我为 Prisma 中间件创建了一个单独的 ts 文件,并将其导入到 main.ts 文件中。
这是我的代码:
Prisma 中间件:
import { Prisma, PrismaClient } from '@prisma/client';
import * as bcrypt from 'bcrypt';
export function passwordMiddleware() {
const prisma: PrismaClient = new 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 await next(params);
});
}
main.ts 文件:
import { Logger } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app/app.module';
import { passwordMiddleware } from './app/core/prisma/middleware';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const globalPrefix = 'api';
app.setGlobalPrefix(globalPrefix);
const port = process.env.PORT || 3333;
//******** Start Prisma Middlewares ********
passwordMiddleware();
//******** End Prisma Middlewares ********
await app.listen(port, () => {
Logger.log('Listening at http://localhost:' + port + '/' + globalPrefix);
});
}
bootstrap();
Prisma 型号:
model User {
id String @id @default(uuid())
email String @unique
password String
name String?
gender String?
address String?
telecom String?
birthDate DateTime?
createdAt DateTime @default(now())
}
授权控制器:
@Post('register')
register(@Body() registerDto: RegisterDto) {
return this.authService.register(registerDto);
}
授权服务:
register(registerDto: RegisterDto): Promise<User> {
return this.prismaService.user.create({
data: {
email: registerDto.email,
password: registerDto.password,
},
});
}
最后你没有改变返回的参数。尝试添加:params.args.data = user;
在散列密码之后。
您使用的 PrismaClient
与您查询时使用的相同吗?
看来在passwordMiddleware
方法中,你是这样做的:
const prisma: PrismaClient = new PrismaClient();
这将创建一个新的 PrismaClient
实例,中间件将只在这个特定实例上工作。
您需要使用与查询相同的实例来注册中间件。
您将中间件应用于 express 本身,您应该在 PrismaService onModuleInit
方法中将中间件应用于 prisma 客户端,即:
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
async onModuleInit() {
await this.$connect();
this.$use(async (params, 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);
});
}
我想使用 Prisma 中间件在创建 API 时对用户密码进行哈希处理,但它不起作用。我为 Prisma 中间件创建了一个单独的 ts 文件,并将其导入到 main.ts 文件中。
这是我的代码:
Prisma 中间件:
import { Prisma, PrismaClient } from '@prisma/client';
import * as bcrypt from 'bcrypt';
export function passwordMiddleware() {
const prisma: PrismaClient = new 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 await next(params);
});
}
main.ts 文件:
import { Logger } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app/app.module';
import { passwordMiddleware } from './app/core/prisma/middleware';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const globalPrefix = 'api';
app.setGlobalPrefix(globalPrefix);
const port = process.env.PORT || 3333;
//******** Start Prisma Middlewares ********
passwordMiddleware();
//******** End Prisma Middlewares ********
await app.listen(port, () => {
Logger.log('Listening at http://localhost:' + port + '/' + globalPrefix);
});
}
bootstrap();
Prisma 型号:
model User {
id String @id @default(uuid())
email String @unique
password String
name String?
gender String?
address String?
telecom String?
birthDate DateTime?
createdAt DateTime @default(now())
}
授权控制器:
@Post('register')
register(@Body() registerDto: RegisterDto) {
return this.authService.register(registerDto);
}
授权服务:
register(registerDto: RegisterDto): Promise<User> {
return this.prismaService.user.create({
data: {
email: registerDto.email,
password: registerDto.password,
},
});
}
最后你没有改变返回的参数。尝试添加:params.args.data = user;
在散列密码之后。
您使用的 PrismaClient
与您查询时使用的相同吗?
看来在passwordMiddleware
方法中,你是这样做的:
const prisma: PrismaClient = new PrismaClient();
这将创建一个新的 PrismaClient
实例,中间件将只在这个特定实例上工作。
您需要使用与查询相同的实例来注册中间件。
您将中间件应用于 express 本身,您应该在 PrismaService onModuleInit
方法中将中间件应用于 prisma 客户端,即:
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
async onModuleInit() {
await this.$connect();
this.$use(async (params, 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);
});
}