微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ApiPlatform - collectionOperations 没有通过投票者的支持方法 标准化方法:支持归一化方法

如何解决ApiPlatform - collectionOperations 没有通过投票者的支持方法 标准化方法:支持归一化方法

我将 Symfony5ApiPlaform 一起使用

我遇到了一个小问题,但找不到任何材料来解决

所以,我有一个对 API 开放的实体,我想从中恢复一个列表

我自然是这样设置 collectionoperations :

 *     collectionoperations={
 *          "get"={
 *              "mehtod"="GET",*              "security"="is_granted('LIST',object)",*              "normalization_context"={"groups"={"user:list"}},*          }
 *     },

并在我的选民中检查像这样的 supports 方法

    protected function supports($attribute,$subject): bool
    {
        return parent::supports($attribute,$subject)
            && (
                $subject instanceof User
                || $this->arrayOf($subject,User::class)
            );
    }

我认为 arrayOf 条件会检查对象列表,但我收到了一个分页对象,因此只能检查它是否是一个分页对象,这可能会给我的其他选民带来问题。 无论如何,只需在 Paginator 方法中返回我的 VoteOnAttribute 对象(已经尝试过)

所以我的问题是,有没有办法通过将对象从注释发送给选民来检查对象列表上的授权?

谢谢!

解决方法

收集操作不会通过您的 User::class。 (它可能会像分页器一样通过……)

方法 1:过滤您的收藏

您可以通过更改用户的查询构建器来过滤您的集合。 见https://api-platform.com/docs/core/extensions/

方式 2:自定义规范化器

您可以在自定义规范器中检查安全性并更改 serialization_context 或在用户无权访问对象时抛出异常。这种方法会对性能产生负面影响。

https://api-platform.com/docs/core/serialization/#changing-the-serialization-context-on-a-per-item-basis

这是我的规范化器的示例

标准化方法:


    public function normalize($object,string $format = null,array $context = []): array
    {
        $context['groups'] = []; //remove all groups
        $context['groups'][] = 'read:always';
        
        if ($this->security->isGranted('ENTITY_ACCESS',$object)) {
            $context['groups'][] = 'read'; //allow to read properties with @Groups{{"read"}}
        } else {
            throw new ClientError(ClientErrorType::CHECK_ACCESS,['type' => $this->getEntityName($object)]);
        }

        $context['groups'] = array_unique($context['groups']);
        $context['resource_normalizer_call_data'][] = $object->getId();
        return $this->normalizer->normalize($object,$format,$context);
    }

支持归一化方法

    public function supportsNormalization($data,array $context = []): bool
    {

        if ( //is object doctrine entity?
            !$this->isEntity($this->managerRegistry->getManager(),$data)
            || !isset($context['graphql_operation_name'])

        ) {
            return false;
        }

        if ( //dont normalize same entity twice! 
            isset($context['resource_normalizer_call_data'])
            && in_array($data->getId(),$context['resource_normalizer_call_data'])
        ) {
            return false;
        }

        return true;
    }

,

通过按如下方式检查查询结果的类型,我找到了一种适合我的解决方法:

    protected function supports($attribute,$subject): bool
    {
        return parent::supports($attribute,$subject)
            && (
                $subject instanceof User ||
                $this->arrayOf($subject,User::class) ||
                (is_a($subject,Paginator::class) &&
                    is_a(iterator_to_array($subject->getIterator())[0],User::class))

            );
    }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。