Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rest 如何根据用户设置规范化组';s角色和请求方法_Rest_Api_Symfony_Api Platform.com - Fatal编程技术网

Rest 如何根据用户设置规范化组';s角色和请求方法

Rest 如何根据用户设置规范化组';s角色和请求方法,rest,api,symfony,api-platform.com,Rest,Api,Symfony,Api Platform.com,我正在创建一个沙盒应用程序作为Api平台实践,我有以下问题需要解决: 让我们考虑用户实体的REST端点: 免责声明在代码示例中,还有一些属性,但整个概念适用于此 集合获取(aka./api/users)仅对管理员用户可用(所有属性都可用,可能我们不包括散列密码) POST-每个人都应该有权访问以下属性:用户名、电子邮件、普通密码(不只是在有人要求时才保留) 修补/放置-这里变得相当棘手:我希望那些具有管理员角色的人能够访问用户名、电子邮件和密码字段。而那些拥有者只能更改明文密码 删除-只有角色管

我正在创建一个沙盒应用程序作为Api平台实践,我有以下问题需要解决:
让我们考虑用户实体的REST端点:
免责声明在代码示例中,还有一些属性,但整个概念适用于此

集合获取(aka./api/users)仅对管理员用户可用(所有属性都可用,可能我们不包括散列密码)

POST-每个人都应该有权访问以下属性:用户名、电子邮件、普通密码(不只是在有人要求时才保留)

修补/放置-这里变得相当棘手:我希望那些具有管理员角色的人能够访问用户名、电子邮件和密码字段。而那些拥有者只能更改明文密码

删除-只有角色管理员和所有者可以删除

我将从资源配置开始

resources:
    App\Entity\User:
        # attributes:
        #     normalization_context:
        #         groups: ['read', 'put', 'patch', 'post', 'get', 'collection:get']
        #     denormalization_context:
        #         groups: ['read', 'put', 'patch', 'post', 'get', 'collection:get']
        collectionOperations:
            get:
                security: 'is_granted("ROLE_ADMIN")'
                normalization_context: { groups: ['collection:get'] }
            post: 
                normalization_context: { groups: ['admin:post', 'post'] }
        itemOperations:
            get:
                normalization_context: { groups: ['admin:get', 'get'] }
                security: 'is_granted("ROLE_ADMIN") or object == user'
            put:
                normalization_context: { groups: ['admin:put', 'put'] }
                security: 'is_granted("ROLE_ADMIN") or object == user'
            patch:
                normalization_context: { groups: ['admin:patch', 'patch'] }
                security: 'is_granted("ROLE_ADMIN") or object == user'
            delete:
                security: 'is_granted("ROLE_ADMIN") or object == user'
下面是序列化程序配置

App\Entity\User:
    attributes:
        username:
            groups: ['post', 'admin:put', 'admin:patch', 'collection:get', 'get']
        email:
            groups: ['post', 'admin:put', 'admin:patch', 'collection:get', 'get']
        firstName:
            groups: ['post', 'admin:put', 'admin:patch', 'collection:get', 'get']
        lastName:
            groups: ['post', 'admin:put', 'admin:patch', 'collection:get', 'get']
        plainPassword:
            groups: ['post', patch]
        createdAt:
            groups: ['get', 'collection:get']
        lastLoginDate:
            groups: ['get', 'collection:get']
        updatedAt:
            groups: ['collection:get']
这是上下文组生成器(注册为服务,如API平台文档中所述

<?php

namespace App\Serializer;

use Symfony\Component\HttpFoundation\Request;
use ApiPlatform\Core\Serializer\SerializerContextBuilderInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;

final class AdminContextBuilder implements SerializerContextBuilderInterface
{
    private $decorated;
    private $authorizationChecker;

    public function __construct(SerializerContextBuilderInterface $decorated, AuthorizationCheckerInterface $authorizationChecker)
    {
        $this->decorated = $decorated;
        $this->authorizationChecker = $authorizationChecker;
    }

    public function createFromRequest(Request $request, bool $normalization, ?array $extractedAttributes = null): array
    {
        $context = $this->decorated->createFromRequest($request, $normalization, $extractedAttributes);

        if ($this->authorizationChecker->isGranted('ROLE_ADMIN')) {
            switch($request->getMethod()) {
                case 'GET':
                    $context['groups'][] = 'admin:get';
                    break;
                case 'POST':
                    $context['groups'][] = 'admin:post';
                case 'PUT':
                    $context['groups'][] = 'admin:put';
                case 'PATCH':
                    $context['groups'][] = 'admin:patch';
            }
        }

        return $context;
    }
}

在调查文档、浏览youtube以及最重要的是对上述用户资源进行实验之后,我想出了解决方案
让我们再次从配置开始:

resources:
    App\Entity\User:
        collectionOperations:
            get:
                security: 'is_granted("ROLE_ADMIN")'
                normalization_context: { groups: ['collection:get'] }
                denormalization_context: { groups: ['collection:get'] }
            post:
                normalization_context: { groups: ['post'] }
                denormalization_context: { groups: ['post'] }
        itemOperations:
            get:
                normalization_context: { groups: ['get'] }
                security: 'is_granted("ROLE_ADMIN") or object == user'
            patch:
                normalization_context: { groups: ['patch'] }
                denormalization_context: { groups: ['patch'] }
                security: 'is_granted("ROLE_ADMIN") or object == user'
            delete:
                security: 'is_granted("ROLE_ADMIN") or object == user'
起始点之间的主要区别在于,永远不应在操作组中声明管理操作,因为它们将默认添加到上下文中。

接下来是属性组,我们在其中定义某些属性上可用的所有操作

App\Entity\User:
    attributes:
        id:
            groups: ['get', 'collection:get']
        username:
            groups: ['post', 'admin:patch', 'get', 'collection:get']
        email:
            groups: ['post', 'admin:patch', 'get', 'collection:get']
        plainPassword:
            groups: ['post', 'patch', 'collection:get']
        firstName:
            groups: ['post', 'patch', 'get', 'collection:get']
        lastName:
            groups: ['post', 'get', 'collection:get']
        createdAt:
            groups: ['get', 'collection:get']
        lastLoginDate:
            groups: ['get', 'collection:get']
        updatedAt:
            groups: ['collection:get']
这与问题中的完全相同,我们需要配置的唯一一件事是哪些操作需要成为“管理员”。这可以根据您的需要进行更改,无论您编写博客、库、商店或其他什么,并且需要在API上对每个角色执行一些自定义操作。

最后是自定义上下文生成器

<?php

namespace App\Serializer;

use Symfony\Component\HttpFoundation\Request;
use ApiPlatform\Core\Serializer\SerializerContextBuilderInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;

final class AdminContextBuilder implements SerializerContextBuilderInterface
{
    private $decorated;
    private $authorizationChecker;

    public function __construct(SerializerContextBuilderInterface $decorated, AuthorizationCheckerInterface $authorizationChecker)
    {
        $this->decorated = $decorated;
        $this->authorizationChecker = $authorizationChecker;
    }

    public function createFromRequest(Request $request, bool $normalization, ?array $extractedAttributes = null): array
    {
        $context = $this->decorated->createFromRequest($request, $normalization, $extractedAttributes);

        if ($this->authorizationChecker->isGranted('ROLE_ADMIN')) {
            $context['groups'][] = 'admin:patch';
            $context['groups'][] = 'admin:post';
            $context['groups'][] = 'admin:get';
        }

        return $context;
    }
}