首页 > 解决方案 > NestJS 拒绝正文错误的 POST 请求(验证 POST 正文类型)

问题描述

我想对我的 POST 正文进行类型检查。只需检查以确保用户输入的正文具有给定类型的部分或全部属性。

我有复杂的类型,例如 SalesOrder。它具有嵌套的对象、对象数组等。我想允许用户仅使用父对象的某些属性进行 POST

例如,假设这是我的完整 SalesOrder 类型:

export class SalesOrder {
    ID: number,
    DeliveryInfo: {
        ActualDeliveryDateTime: string
        ScheduledDeliveryDateTime: string
    }

    SalesOrderGeneralInfo: {
        Branch: IDValue
        InventoryLocation: IDValue
        SalesOrderClassification: IDValue
        Reference: string
    }

    SalesOrderInsuranceInfo: {
        CoverageVerified: string
        InsuranceVerified: string
        SignatureGeneratedByProvider: string
    }

}

interface IDValue {
    ID: string,
    Value: string;
}

我想允许用户在他们的帖子正文中包含这些属性的子集,目前由类型 SalesOrderUpdate 表示。从技术上讲,此类中的所有属性都是可选的:

export class SalesOrderUpdateDto {
    ID: number;
    SalesOrder: SalesOrderUpdate
}

export class SalesOrderUpdate {
    DeliveryInfo: {
        ActualDeliveryDateTime: string;
        ScheduledDeliveryDateTime: string;
    }

    SalesOrderGeneralInfo: {
        Branch: IDValue
        InventoryLocation: IDValue
        SalesOrderClassification: IDValue
        Reference: string;
    }

}

现在的关键是,他们可以从 DTO 类型发送任意数量的属性。 因此,如果用户只想使用 SalesOrderGeneralInfo.Branch.Value 进行 POST,则应该允许这样做。如果他们想发送全身,那应该被允许。但是,如果他们想发送带有 SalesOrderInsuranceInfo 的 POST,那应该被阻止。如果他们想发送一个随处可见的随机属性的 POST,那绝对应该被阻止。目前,NestJS 将允许 POST 正文中的任何内容,这对我来说很疯狂。

这是我的基本控制器:

@Post('/update')
async salesOrderUpdate(
@Body() body: SalesOrderUpdateDto,
) {
    return await this.salesOrderService.updateSalesOrder(`${body.ID}`, body.SalesOrder);
}

我尝试在控制器上使用 ValidationPipe:

@Post('/update')
@UsePipes(new ValidationPipe({ whitelist: true }))
async salesOrderUpdate(
@Body() body: SalesorderUpdateDto,

然后我不得不注释 DTO:

export class SalesorderUpdateDto {
    @IsNumber()
    ID: number;

    @IsNotEmptyObject()
    @ValidateNested()
    SalesOrder: SalesOrderUpdate
}

export class SalesOrderUpdate {
    DeliveryInfo: {
        ActualDeliveryDateTime: string;
        ScheduledDeliveryDateTime: string;
    }
...

但这会导致一个空的 SalesOrder 对象。我觉得这应该非常容易实现,但不幸的是 Stack Overflow 上的示例根本没有帮助。我对创建 200 行长的自定义验证器不感兴趣(希望这不是必需的)。我只关心 POST 正文的结构与分配给它的类型相匹配,如果不匹配则请求失败

我简直不敢相信,默认情况下,我可以将类型分配给 POST 正文并提交完全不同类型的内容,而 NestJS 将继续运行而不会出错。

标签: typescriptnestjs

解决方案


推荐阅读