使用 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
对象都要被调用
其实可能只是比较一下用户的 Role
。Symfony 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: 符合条件时跳过
反向逻辑比较安全,减少安全漏洞的机会。
- 用户之前有权限,下一秒可能就没权限了。
- 和更复杂的条件有关,比如别的相关数据的状态