Symfony:为什么在身份验证后应该执行一些用户检查?

Łuk*_*oda 5 authentication symfony

我不明白这一点。UserCheckerInterface有两种方法:checkPreAuthcheckPostAuth。现在让我们看看它们在类中的实现UserChecker

class UserChecker implements UserCheckerInterface
{
    /**
     * {@inheritdoc}
     */
    public function checkPreAuth(UserInterface $user)
    {
        if (!$user instanceof AdvancedUserInterface) {
            return;
        }

        if (!$user->isAccountNonLocked()) {
            $ex = new LockedException('User account is locked.');
            $ex->setUser($user);
            throw $ex;
        }

        if (!$user->isEnabled()) {
            $ex = new DisabledException('User account is disabled.');
            $ex->setUser($user);
            throw $ex;
        }

        if (!$user->isAccountNonExpired()) {
            $ex = new AccountExpiredException('User account has expired.');
            $ex->setUser($user);
            throw $ex;
        }
    }

    /**
     * {@inheritdoc}
     */
    public function checkPostAuth(UserInterface $user)
    {
        if (!$user instanceof AdvancedUserInterface) {
            return;
        }

        if (!$user->isCredentialsNonExpired()) {
            $ex = new CredentialsExpiredException('User credentials have expired.');
            $ex->setUser($user);
            throw $ex;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么应该isCredentialsNonExpired()在身份验证之后进行?难道我们不应该不允许凭证过期的用户进行身份验证吗?还有额外的问题:我们应该在哪里真正进行“身份验证后”检查?设置身份验证令牌后?

mic*_*doo 3

我相信这些方法被拆分的原因是因为在使用基于会话的身份验证时,有些事情您不想每次都检查。

当使用会话时,Symfony 将序列化令牌(和相关用户)。当下一个请求到来时,PreAuthenticatedToken 将包含您授权所需的凭据。

预验证令牌的一些示例是:(从docs窃取)

  • 基于“记住我”cookie 的身份验证。
  • 基于您的会话的身份验证。
  • 使用 HTTP 基本或 HTTP 摘要标头进行身份验证

为了提高性能,如果您在会话中存储了令牌,您可以删除一些检查。我拥有的唯一示例UserCheckerInterface是 Symfony 提供的示例。正如您所看到的,用户帐户的验证是在内部完成的preAuth,并且postAuth仅检查凭据是否已过期。

在实际情况中,查看使用这些方法的服务,您会发现没有太大区别。依次调用GuardAuthenticationProvider两者。

Symfony 的PreAuthenticatedAuthenticationProvider唯一调用postAuth,因此也许 Symfony 中的某个人决定,对于基于会话的身份验证,可以将响应时间缩短几毫秒,他们可以将首次身份验证需要完成的身份验证检查与每个请求需要完成的身份验证检查分开。

就您而言,如果您要创建自定义,UserChecker我认为您可以自己决定是否需要同时使用两者。查明是否有其他捆绑包具有调用其中任一方法的身份验证提供程序。找到所有调用它们的地方,您可能会发现您只需要实现一个,或者,如果您有很多复杂的身份验证逻辑,请将其拆分。