在Symfony 4中,Voter
是一个用于权限检查的组件,它可以用来决定是否允许用户执行某个操作。当你需要对 EntityType
字段进行过滤时,可以使用 Voter
来实现基于用户权限的数据过滤。
Voter: 在Symfony中,Voter
是一个类,它决定了用户是否有权限执行某个操作。Voter
通常会检查用户的角色或其他属性,并返回一个布尔值。
EntityType: 这是一个表单类型,用于在表单中嵌入一个实体选择器。它允许用户从一个预定义的实体列表中选择一个或多个实体。
假设你有一个博客应用,用户可以创建文章并分配给其他用户。你希望只有文章的作者或管理员才能编辑文章。在这种情况下,你可以使用 Voter
来过滤 EntityType
字段,确保只有有权限的用户才能看到和选择特定的用户。
首先,你需要创建一个 Voter
类来处理权限检查。
// 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');
}
}
在 security.yaml
文件中注册你的 Voter
。
# config/packages/security.yaml
security:
# ...
access_decision_manager:
strategy: unanimous
voters:
App\Security\Authorization\Voter\ArticleVoter:
id: 'app.article_voter'
在你的表单类型中使用 Voter
来过滤 EntityType
字段。
// 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
已经在 security.yaml
中正确注册。Voter
中的权限检查逻辑是否正确。AuthorizationCheckerInterface
已经通过构造函数注入到你的表单类型中。解决方法:
Voter
类路径和ID在 security.yaml
中正确无误。Voter
中的权限检查逻辑,确保它按预期工作。通过以上步骤,你应该能够在Symfony 4中使用 Voter
来过滤 EntityType
字段,并根据用户的权限显示适当的数据。
领取专属 10元无门槛券
手把手带您无忧上云