Class-Validator中@IsEmail如何实现多域名白名单校验
class-validator 邮箱域名白名单校验实现方案
首先明确结论:class-validator 内置的
@Contains装饰器仅支持传入单个字符串做包含校验,不支持直接传入域名数组实现多域名匹配,你期望的用法原生无法实现,需要自定义校验装饰器。
自定义装饰器实现步骤
1. 编写自定义校验装饰器
import { registerDecorator, ValidationOptions, ValidationArguments } from 'class-validator'; /** * 校验邮箱域名是否在指定白名单内 * @param allowedDomains 允许的邮箱域名列表 * @param validationOptions 校验配置项 */ export function IsEmailDomainAllowed(allowedDomains: string[], validationOptions?: ValidationOptions) { return function (target: Object, propertyName: string) { registerDecorator({ name: 'isEmailDomainAllowed', target: target.constructor, propertyName: propertyName, constraints: [allowedDomains], options: validationOptions, validator: { validate(value: unknown, args: ValidationArguments) { // 非字符串类型直接校验不通过 if (typeof value !== 'string') return false; const [allowedDomains] = args.constraints as [string[]]; // 拆分邮箱获取域名部分 const emailSuffix = value.split('@').pop()?.toLowerCase(); if (!emailSuffix) return false; // 匹配白名单,自动忽略大小写 return allowedDomains.map(d => d.toLowerCase()).includes(emailSuffix); }, defaultMessage(args: ValidationArguments) { const [allowedDomains] = args.constraints as [string[]]; return `邮箱后缀仅允许为:${allowedDomains.join('、')}`; } } }); }; }
2. 装饰器使用示例
// 先校验邮箱格式合法性,再校验域名白名单,逻辑更严谨 @IsEmail({}, { message: '请输入合法的邮箱格式' }) @IsEmailDomainAllowed(['mydomain.com', 'yourdomain.com', 'wealldomain.com', 'fordomain.com']) public email: string;
拓展说明
- 如果你习惯传入带
@前缀的白名单,只需要修改校验逻辑:将匹配规则替换为return allowedDomains.some(domain => value.toLowerCase().endsWith(domain.toLowerCase()))即可,使用时传入['@mydomain.com', '@yourdomain.com']格式的数组就行。 - 自定义装饰器的错误提示可以通过第二个参数的
message属性覆盖默认提示,灵活适配不同业务场景。
内容的提问来源于stack exchange,提问作者rdurnin
相关产品推荐
相关产品推荐

