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

NestJS中使用Class Validator实现确认密码一致性校验的方法

NestJS中使用Class Validator实现确认密码一致性校验的方法

嗨,我来帮你搞定这个确认密码一致性校验的问题~ 虽然class-validator没有直接提供校验两个字段是否匹配的内置装饰器,但我们可以通过自定义验证逻辑轻松实现,下面给你两种实用的方法:

方法一:使用自定义验证约束类

我们可以创建一个实现ValidatorConstraintInterface的验证类,来定义密码匹配的校验规则,然后在DTO中通过@Validate()装饰器引用它。

步骤1:创建自定义验证约束类

import { ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments } from 'class-validator';

@ValidatorConstraint({ name: 'matchPassword', async: false })
export class MatchPassword implements ValidatorConstraintInterface {
  validate(confirmPassword: string, args: ValidationArguments) {
    // 获取DTO中的password字段值
    const password = args.object[args.constraints[0]];
    return confirmPassword === password;
  }

  defaultMessage(args: ValidationArguments) {
    return '确认密码与密码不匹配';
  }
}

步骤2:在DTO中应用这个验证类

修改你现有的CreatePasswordDTO,给confirmPassword字段添加@Validate()装饰器:

import { MaxLength, IsString, Matches, Validate } from 'class-validator';
import { MatchPassword } from './match-password.validator'; // 替换成你的实际文件路径

export class CreatePasswordDTO {
  @MaxLength(6)
  @IsString()
  @Matches(/^\d{6}$/, { message: "Password must be a 6-digit number" })
  password: string;

  @MaxLength(6)
  @IsString()
  @Matches(/^\d{6}$/, { message: "Confirm Password must be a 6-digit number" })
  @Validate(MatchPassword, ['password']) // 指定要匹配的字段为password
  confirmPassword: string;
}

方法二:封装成自定义装饰器(更简洁复用)

如果这个校验逻辑需要在多个DTO中使用,我们可以把它封装成一个自定义装饰器,用起来更顺手:

步骤1:创建自定义装饰器

import { registerDecorator, ValidationOptions, ValidationArguments } from 'class-validator';

export function IsMatch(property: string, validationOptions?: ValidationOptions) {
  return function (object: Object, propertyName: string) {
    registerDecorator({
      name: 'isMatch',
      target: object.constructor,
      propertyName: propertyName,
      constraints: [property],
      options: validationOptions,
      validator: {
        validate(value: any, args: ValidationArguments) {
          const [relatedPropertyName] = args.constraints;
          const relatedValue = args.object[relatedPropertyName];
          return value === relatedValue;
        },
        defaultMessage(args: ValidationArguments) {
          const [relatedPropertyName] = args.constraints;
          return `${propertyName} must match ${relatedPropertyName}`;
        },
      },
    });
  };
}

步骤2:在DTO中使用自定义装饰器

现在你的DTO可以更简洁:

import { MaxLength, IsString, Matches } from 'class-validator';
import { IsMatch } from './is-match.decorator'; // 替换成你的实际文件路径

export class CreatePasswordDTO {
  @MaxLength(6)
  @IsString()
  @Matches(/^\d{6}$/, { message: "Password must be a 6-digit number" })
  password: string;

  @MaxLength(6)
  @IsString()
  @Matches(/^\d{6}$/, { message: "Confirm Password must be a 6-digit number" })
  @IsMatch('password', { message: '确认密码与密码不匹配' }) // 直接使用自定义装饰器
  confirmPassword: string;
}

最后提醒

别忘了确保你已经在NestJS的main.ts中启用了ValidationPipe,这样才能让class-validator的校验生效:

import { ValidationPipe } from '@nestjs/common';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe());
  await app.listen(3000);
}
bootstrap();

这样就能完美实现密码和确认密码的一致性校验啦~

备注:内容来源于stack exchange,提问作者Ugwu Somto

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 10:39:52