首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Symfony4 -如何使用Voter过滤EntityType字段

在Symfony 4中,Voter 是一个用于权限检查的组件,它可以用来决定是否允许用户执行某个操作。当你需要对 EntityType 字段进行过滤时,可以使用 Voter 来实现基于用户权限的数据过滤。

基础概念

Voter: 在Symfony中,Voter 是一个类,它决定了用户是否有权限执行某个操作。Voter 通常会检查用户的角色或其他属性,并返回一个布尔值。

EntityType: 这是一个表单类型,用于在表单中嵌入一个实体选择器。它允许用户从一个预定义的实体列表中选择一个或多个实体。

应用场景

假设你有一个博客应用,用户可以创建文章并分配给其他用户。你希望只有文章的作者或管理员才能编辑文章。在这种情况下,你可以使用 Voter 来过滤 EntityType 字段,确保只有有权限的用户才能看到和选择特定的用户。

实现步骤

  1. 创建Voter

首先,你需要创建一个 Voter 类来处理权限检查。

代码语言:txt
复制
// src/Security/Authorization/Voter/ArticleVoter.php
namespace App\Security\Authorization\Voter;

use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use App\Entity\Article;

class ArticleVoter extends Voter
{
    const ARTICLE_EDIT = 'ARTICLE_EDIT';

    protected function supports($attribute, $subject)
    {
        return in_array($attribute, [self::ARTICLE_EDIT]) && $subject instanceof Article;
    }

    protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
    {
        $user = $token->getUser();

        if (!$user instanceof User) {
            return false;
        }

        switch ($attribute) {
            case self::ARTICLE_EDIT:
                return $this->canEdit($subject, $user);
        }

        throw new \LogicException('This voter does not support the attribute "' . $attribute . '".');
    }

    private function canEdit(Article $article, User $user)
    {
        return $article->getAuthor() === $user || $user->hasRole('ROLE_ADMIN');
    }
}
  1. 注册Voter

security.yaml 文件中注册你的 Voter

代码语言:txt
复制
# config/packages/security.yaml
security:
    # ...
    access_decision_manager:
        strategy: unanimous
    voters:
        App\Security\Authorization\Voter\ArticleVoter:
            id: 'app.article_voter'
  1. 使用Voter过滤EntityType字段

在你的表单类型中使用 Voter 来过滤 EntityType 字段。

代码语言:txt
复制
// src/Form/Type/ArticleType.php
namespace App\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\EntityType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use App\Entity\Article;
use App\Entity\User;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;

class ArticleType extends AbstractType
{
    private $authorizationChecker;

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

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('author', EntityType::class, [
                'class' => User::class,
                'query_builder' => function (UserRepository $er) {
                    return $er->createQueryBuilder('u')
                        ->where('u.id = :userId')
                        ->setParameter('userId', $this->authorizationChecker->isGranted('ARTICLE_EDIT', $article) ? $article->getAuthor()->getId() : null);
                },
                'choice_label' => 'username',
            ])
            // ...
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Article::class,
        ]);
    }
}

遇到问题的原因及解决方法

问题: 如果在使用 Voter 过滤 EntityType 字段时遇到问题,可能是由于以下原因:

  • Voter未正确注册: 确保你的 Voter 已经在 security.yaml 中正确注册。
  • 权限检查逻辑错误: 检查 Voter 中的权限检查逻辑是否正确。
  • 依赖注入问题: 确保 AuthorizationCheckerInterface 已经通过构造函数注入到你的表单类型中。

解决方法:

  • 确认 Voter 类路径和ID在 security.yaml 中正确无误。
  • 调试 Voter 中的权限检查逻辑,确保它按预期工作。
  • 如果使用依赖注入,确保服务容器能够正确解析并注入所需的依赖。

通过以上步骤,你应该能够在Symfony 4中使用 Voter 来过滤 EntityType 字段,并根据用户的权限显示适当的数据。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

    领券