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);
}
通過實現(xiàn) vote() 方法,結(jié)合 DI 幾乎可以實現(xiàn)任意想要的判斷條件,但是有一個巨大的開銷:
NOTE: 在結(jié)果沒有確定之前,所有的
Voter對象都要被調(diào)用
其實可能只是比較一下用戶的 Role。Symfony 5.4 通過實現(xiàn)這兩個額外的方法解決這個問題:
/**
* 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: 符合條件時跳過
反向邏輯比較安全,減少安全漏洞的機會。
- 用戶之前有權(quán)限,下一秒可能就沒權(quán)限了。
- 和更復(fù)雜的條件有關(guān),比如別的相關(guān)數(shù)據(jù)的狀態(tài)