使用 Symfony 5.4 优化 Voter 性能

2021-12-04  本文已影响0人  forks1990

Voter 有很强的灵活性:

interface VoterInterface
{
    public const ACCESS_GRANTED = 1;
    public const ACCESS_ABSTAIN = 0;
    public const ACCESS_DENIED = -1;

    /**
     * Returns the vote for the given parameters.
     *
     * This method must return one of the following constants:
     * ACCESS_GRANTED, ACCESS_DENIED, or ACCESS_ABSTAIN.
     *
     * @param mixed $subject    The subject to secure
     * @param array $attributes An array of attributes associated with the method being invoked
     *
     * @return int either ACCESS_GRANTED, ACCESS_ABSTAIN, or ACCESS_DENIED
     */
    public function vote(TokenInterface $token, $subject, array $attributes);
}

通过实现 vote() 方法,结合 DI 几乎可以实现任意想要的判断条件,但是有一个巨大的开销:

NOTE: 在结果没有确定之前,所有的 Voter 对象都要被调用

其实可能只是比较一下用户的 RoleSymfony 5.4 通过实现这两个额外的方法解决这个问题:

/**
 * Let voters expose the attributes and types they care about.
 *
 * By returning false to either `supportsAttribute` or `supportsType`, the
 * voter will never be called for the specified attribute or subject.
 *
 * @author Jérémy Derussé <jeremy@derusse.com>
 */
interface CacheableVoterInterface extends VoterInterface
{
    public function supportsAttribute(string $attribute): bool;

    /**
     * @param string $subjectType The type of the subject inferred by `get_class` or `get_debug_type`
     */
    public function supportsType(string $subjectType): bool;
}

如果这两个方法中有一个返回 false,则Symfony再遇到相同的 $subject 类型和/或 $attribute的时候跳过这个Voter。

NOTE: 符合条件时跳过

反向逻辑比较安全,减少安全漏洞的机会。

  1. 用户之前有权限,下一秒可能就没权限了。
  2. 和更复杂的条件有关,比如别的相关数据的状态
上一篇下一篇

猜你喜欢

热点阅读