Symfony:为什么在认证后应该进行一些用户检查?

时间:2016-06-16 17:08:55

标签: 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;
        }
    }
}

为什么isCredentialsNonExpired()在身份验证后完成?难道我们不允许具有过期凭据的用户进行身份验证吗?和奖金问题:我们应该在哪里真正做到这一点"发布身份验证"校验?设置身份验证令牌后?

1 个答案:

答案 0 :(得分:2)

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

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

预先验证的令牌的一些示例是:(从docs偷来)

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

如果您在会话中存储了令牌,则可以提高性能,您可以删除一些检查。我对UserCheckerInterface的唯一例子是Symfony提供的例子。如您所见,用户帐户的验证是在preAuth内完成的,postAuth仅检查凭据是否已过期。

在查看使用这些方法的服务的实际情况中,您可以看到没有太多区别。 GuardAuthenticationProvider按顺序调用。

Symfony的PreAuthenticatedAuthenticationProvider只调用postAuth所以也许Symfony的某个人决定基于会话的身份验证可以减少响应时间几毫秒,他们可以分离需要在第一次身份验证时进行的身份验证检查那些需要在每次请求时完成的事情。

在您的情况下,如果您正在创建自定义UserChecker,我认为您可以自行决定是否需要同时使用这两者。找出是否有其他捆绑包,其中包含身份验证提供程序调用这些方法之一。查找调用它们的所有位置,您可能会发现只需要实现一个,或者,如果您有许多复杂的身份验证逻辑,则将其拆分。