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

API Platform 4(Symfony 8):CQRS架构下DELETE操作密码确认最佳实践

API Platform 4 + Symfony 8 敏感DELETE操作密码验证方案

针对你的需求(REST规范、CQRS分层、领域层负责密码验证、HTTP/领域分离),以下是落地性强的推荐实现模式:

一、自定义头 vs 请求体:选型结论

  • 自定义头X-CURRENT-PASSWORD是更稳妥的选择:虽然HTTP标准未禁止DELETE带请求体,但大量客户端、网关或API网关对DELETE请求体的支持存在兼容性问题,符合REST实践中"DELETE请求无主体"的约定。
  • 必须强制HTTPS传输,避免明文密码泄露。

二、API Platform生态下的标准可复用实现

1. 用标记接口统一标识需验证的命令

创建领域层标记接口,用于区分需要密码验证的命令,实现复用逻辑:

// src/Domain/Command/RequiresPasswordVerification.php
interface RequiresPasswordVerification
{
    public function getCurrentPassword(): string;
}

让敏感删除命令实现该接口:

// src/Domain/Command/DeleteUserAccountCommand.php
class DeleteUserAccountCommand implements RequiresPasswordVerification
{
    public function __construct(
        public readonly string $userId,
        public readonly string $currentPassword
    ) {}

    public function getCurrentPassword(): string
    {
        return $this->currentPassword;
    }
}

2. API资源配置与OpenAPI文档自动生成

在API资源的DELETE操作中,通过openapiContext明确声明需要传递的自定义头,自动生成规范的OpenAPI文档:

// src/Api/Resource/UserResource.php
#[ApiResource(
    operations: [
        new Delete(
            uriTemplate: '/users/{id}',
            input: DeleteUserAccountInput::class,
            openapiContext: [
                'parameters' => [
                    [
                        'name' => 'X-CURRENT-PASSWORD',
                        'in' => 'header',
                        'required' => true,
                        'schema' => ['type' => 'string'],
                        'description' => '当前用户密码,用于验证操作权限'
                    ]
                ]
            ]
        )
    ]
)]
class UserResource
{
    // 资源定义
}

3. HTTP层处理器:请求头到命令的映射

在API Platform处理器中,从请求栈获取自定义头,注入到领域命令中,保持HTTP层仅做参数传递:

// src/Api/Processor/DeleteUserAccountProcessor.php
class DeleteUserAccountProcessor implements ProcessorInterface
{
    public function __construct(
        private readonly CommandBusInterface $commandBus,
        private readonly RequestStack $requestStack
    ) {}

    public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): void
    {
        $currentPassword = $this->requestStack->getCurrentRequest()->headers->get('X-CURRENT-PASSWORD');
        
        $command = new DeleteUserAccountCommand(
            $uriVariables['id'],
            $currentPassword
        );

        $this->commandBus->dispatch($command);
    }
}

如果要进一步复用,可封装通用处理器装饰器,对所有实现RequiresPasswordVerification的命令自动注入头参数。

4. 领域层:密码验证的核心逻辑

将密码验证放在领域服务中,确保业务逻辑不泄露到HTTP层:

// src/Domain/Service/UserDomainService.php
class UserDomainService
{
    public function __construct(private readonly PasswordHasherInterface $passwordHasher) {}

    public function verifyCurrentPassword(User $user, string $currentPassword): void
    {
        if (!$this->passwordHasher->verify($user->getPassword(), $currentPassword)) {
            throw new InvalidPasswordException('当前密码验证失败');
        }
    }
}

在命令Handler中调用该服务完成验证后,执行删除逻辑:

// src/Domain/Handler/DeleteUserAccountHandler.php
class DeleteUserAccountHandler implements CommandHandlerInterface
{
    public function __construct(
        private readonly UserRepositoryInterface $userRepository,
        private readonly UserDomainService $userDomainService
    ) {}

    public function __invoke(DeleteUserAccountCommand $command): void
    {
        $user = $this->userRepository->find($command->userId);
        if (!$user) {
            throw new UserNotFoundException();
        }

        // 领域层密码验证
        $this->userDomainService->verifyCurrentPassword($user, $command->currentPassword);

        // 执行删除操作
        $this->userRepository->remove($user);
    }
}

三、CQRS架构下的团队通用实践

  • 严格分层隔离:HTTP层只做请求参数解析、命令分发;领域层负责所有业务规则(含密码验证);基础设施层处理持久化等技术细节。
  • 复用标记接口:通过RequiresPasswordVerification统一标识需要验证的命令,后续可快速扩展通用逻辑(比如全局异常捕获、日志埋点)。
  • 统一异常处理:在HTTP层捕获领域层抛出的InvalidPasswordException,转换为403 Forbidden响应,保证错误格式一致性。
  • 自动化文档:利用API Platform的openapiContext或自定义属性,自动生成密码验证的接口文档,避免手动维护。

总结

  1. X-CURRENT-PASSWORD自定义头是符合REST实践的合理选择,需强制HTTPS传输。
  2. 采用「标记接口+API资源配置+处理器映射+领域服务验证」的模式,实现可复用性与分层清晰的平衡。
  3. 所有业务逻辑收敛到领域层,HTTP层仅做参数传递,完全符合整洁架构要求。

内容的提问来源于stack exchange,提问作者user22906900

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.02 04:24:53