symfony - 如何在 API 平台中对“GET 项目”请求的 SQL 请求之前验证 UUID 参数?
问题描述
使用:
- PostgreSQL 11 与
uuid_generate_v4
类型 - Symfony 4.4.11
- API 平台 2.5.6
我有一个具有以下 ID 的实体:
/**
* @ORM\Entity(repositoryClass="App\Repository\ContractRepository")
* @ORM\HasLifecycleCallbacks
*/
class Contract
{
/**
* @ORM\Id()
* @ORM\GeneratedValue(strategy="UUID")
* @ORM\Column(name="id", type="guid", unique=true)
*/
private $id;
[...]
我使用 Api Platform 生成以下路线:
App\Entity\Contract:
itemOperations:
get:
所以我得到了一个生成的路线/contracts/{id}
目前,如果我这样做/contracts/TEST
,它将尝试在 where 子句中使用“TEST”执行 SQL 请求,因此将作为500
.
我想通过断言{id}
参数是 aUUID_v4
并返回 a400
如果不是来防止这种行为。
解决方案
此行为是 DBMS 特定的,因此您必须添加自己的逻辑。
检索给定 ID 的实体的 API 平台组件是ItemDataProviderInterface。
- 首先,我将声明一个新的异常
MalformedUuidException
。 - 接下来,我会将此异常转换为 400 错误。
- 最后,我将创建一个新的 ItemDataProviderInterface 实现,包装 ORM 并向 ID 添加一些检查:
class ContractDataProvider implements RestrictedDataProviderInterface, ItemDataProviderInterface
{
/** @var ItemDataProviderInterface */
private $realDataProvider;
public function __construct(ItemDataProviderInterface $realDataProvider)
{
$this->realDataProvider = $realDataProvider;
}
public function getItem(string $resourceClass, $id, string $operationName = null, array $context = [])
{
$uuidPattern = '/^[a-f0-9]{8}-([a-f0-9]{4}-){3}[a-f0-9]{12}$/i';
if (preg_match($uuidPattern, $id) === 1) {
return $this->realDataProvider->getItem($resourceClass, ['id' => $id], $operationName, $context);
} else {
throw new MalformedUuidException("the given ID \"$id\" is not a valid UUID.");
}
}
public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
{
return $resourceClass === Contract::class;
}
}
# config/services.yaml
App\DataProvider\ContractDataProvider:
arguments:
$realDataProvider: '@api_platform.doctrine.orm.default.item_data_provider'
但是,请注意,该getItem()
方法的协定并未指定MalformedUuidException
异常,因此此实现打破了 Liskov 替换原则。
考虑改为返回 null 并对 404 错误感到满意。
推荐阅读
- node.js - 缺少模块的错误
- c# - 无法完成可观察
- opencv - 无法生成 createsamples 和 traincascade 可执行文件
- javascript - 比较两个 JavaScript 对象/数组值
- javascript - 如何从嵌套钩子函数访问数据属性?
- wcf - WCF:找不到 X.509 证书
- arrays - 动态数组不接受在 1x2 中重新调整尺寸(2x2 和 2x1 有效)
- python - 如何将充满数字字符串的csv文件读取到numpy数组中
- python - 如何快速向数据框插入一行?
- flutter - 当我从 FLUTTER 的下拉列表中更新数据时出错?