代码之家  ›  专栏  ›  技术社区  ›  Syndesi

Symfony 4:条令实体根据角色返回不同的数据_*

  •  0
  • Syndesi  · 技术社区  · 6 年前

    我有一个 Account -应根据当前登录用户的角色返回不同数据的实体:

    return [                                     // to be returned if user has role:
        'id' => $this->id,                       // ROLE_USER, ROLE_PAYED, ROLE_ADMIN
        'name' => $this->name,                   // ROLE_USER, ROLE_PAYED, ROLE_ADMIN
        'hobbies' => ['some', 'tags'],           // ROLE_PAYED, ROLE_ADMIN
        'roles' => ['ROLE_USER', 'ROLE_PAYED']   // ROLE_ADMIN
    ];
    

    如果我在一个控制器中做这个改变,我只需要调用 voter .但我想在实体的 jsonSerialize -函数,以便在每个请求中毫无例外地实现它。

    我猜真正的问题是“如何让选民进入实体”,但实际上我对Symfony了解不够(现在只使用了10天)。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Tony    6 年前

    选民是服务,服务真的不应该在实体内部。实体不应了解视图或控制器中的任何内容。如果您发现自己需要实体内部的服务,这通常是您需要重新思考架构的标志。

    我会采取的方法是创建一个 JsonSerializeAccount 使用 AuthorizationChecker 创建json数组。

    <?php
    
    namespace App\Service;
    
    use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
    use App\Entity\Account;
    
    class JsonSerializeAccount {
        /**
         * @var AuthorizationCheckerInterface
         */
        private $authorizationChecker;
    
        public function __construct(AuthorizationCheckerInterface $authorizationChecker)
        {
            $this->authorizationChecker = $authorizationChecker;
        }
    
        public function jsonSerialize(Account $account): array
        {
            $json = [
                'id' => $account->getId(),
                'name' => $account->getName(),
            ];
    
            if ($this->authorizationChecker->isGranted('view_hobbies', $account)) {
                $json['hobbies'] = $account->getHobbies();
            }
    
            if ($this->authorizationChecker->isGranted('view_roles', $account)) {
                $json['roles'] = $account->getRoles();
            }
    
            return $json;
        }
    }