Следите за новинками
в нашем Telegram канале. Жми, чтобы подписаться:)
593 of 1361 menu
◀ ▶

Метод vote класса Voter

Метод vote класса Voter является центральным элементом системы авторизации Symfony. Он вызывается менеджером решений AccessDecisionManager для вычисления итогового результата голосования всех зарегистрированных voter-ов. Метод принимает объект токена $token, произвольный атрибут $attribute и субъект доступа $subject. Возвращает одна из трёх констант: ACCESS_GRANTED, ACCESS_DENIED или ACCESS_ABSTAIN.

Синтаксис

public function vote(TokenInterface $token, mixed $subject, array $attributes): int

Пример

Давайте создадим собственный voter, который разрешает доступ к объекту Article только его автору. Для начала создадим сущность:

<?php namespace AppEntity; use DoctrineORMMapping as ORM; #[ORMEntity] class Article { #[ORMId, ORMGeneratedValue, ORMColumn(type: 'integer')] private ?int $id = null; #[ORMColumn(type: 'string', length: 255)] private string $title = ''; #[ORMColumn(type: 'text')] private string $text = ''; #[ORMManyToOne(targetEntity: User::class)] private ?User $author = null; public function getId(): ?int { return $this->id; } public function getTitle(): string { return $this->title; } public function setTitle(string $title): self { $this->title = $title; return $this; } public function getText(): string { return $this->text; } public function setText(string $text): self { $this->text = $text; return $this; } public function getAuthor(): ?User { return $this->author; } public function setAuthor(?User $author): self { $this->author = $author; return $this; } } ?>

Теперь создадим voter, который в методе vote проверяет, является ли текущий пользователь автором статьи:

<?php namespace AppSecurity; use AppEntityArticle; use AppEntityUser; use SymfonyComponentSecurityCoreAuthenticationTokenTokenInterface; use SymfonyComponentSecurityCoreAuthorizationVoterVoter; class ArticleVoter extends Voter { public const EDIT = 'ARTICLE_EDIT'; public const VIEW = 'ARTICLE_VIEW'; protected function supports(string $attribute, mixed $subject): bool { if (!in_array($attribute, [self::EDIT, self::VIEW])) { return false; } if (!$subject instanceof Article) { return false; } return true; } protected function voteOnAttribute(string $attribute, mixed $subject, TokenInterface $token): bool { $user = $token->getUser(); if (!$user instanceof User) { return false; } /** @var Article $article */ $article = $subject; return $user === $article->getAuthor(); } } ?>

Теперь используем метод vote напрямую для проверки доступа к статье:

<?php namespace AppController; use AppEntityArticle; use AppEntityUser; use AppSecurityArticleVoter; use SymfonyBundleFrameworkBundleControllerAbstractController; use SymfonyComponentHttpFoundationResponse; use SymfonyComponentSecurityCoreAuthenticationTokenUsernamePasswordToken; use SymfonyComponentRoutingAttributeRoute; class ArticleController extends AbstractController { #[Route('/article/{id}', name: 'article_show')] public function show(Article $article): Response { $voter = new ArticleVoter(); $user = new User(); $user->setLogin('abcde'); $article->setAuthor($user); $token = new UsernamePasswordToken($user, 'main', $user->getRoles()); $res = $voter->vote($token, $article, [ArticleVoter::VIEW]); return new Response((string) $res); } } ?>

Результат выполнения кода при совпадении автора:

"1"

Пример

Давайте проверим, что вернёт метод vote, если текущий пользователь не является автором статьи:

<?php namespace AppController; use AppEntityArticle; use AppEntityUser; use AppSecurityArticleVoter; use SymfonyBundleFrameworkBundleControllerAbstractController; use SymfonyComponentHttpFoundationResponse; use SymfonyComponentSecurityCoreAuthenticationTokenUsernamePasswordToken; use SymfonyComponentRoutingAttributeRoute; class ArticleController extends AbstractController { #[Route('/article/check', name: 'article_check')] public function check(): Response { $voter = new ArticleVoter(); $author = new User(); $author->setLogin('abcde'); $other = new User(); $other->setLogin('user'); $article = new Article(); $article->setTitle('article'); $article->setAuthor($author); $token = new UsernamePasswordToken($other, 'main', $other->getRoles()); $res = $voter->vote($token, $article, [ArticleVoter::EDIT]); return new Response((string) $res); } } ?>

Результат выполнения кода при несовпадении автора:

"-1"

Смотрите также

  • класс Voter,
    который лежит в основе системы голосования
  • метод supports,
    который определяет, поддерживает ли voter атрибут
  • метод voteOnAttribute,
    который содержит логику проверки доступа
  • атрибут IsGranted,
    который использует voter для проверки прав
← →
↑
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить