Symfony4 没有根据记住我的 cookie 找到用户

Symfony4 does not find user according to remember me cookie

我已将 symfony 4 配置为在用户选中复选框时设置记住我的 cookie。这可以正常工作。但是当我重新启动浏览器并 return 访问该网站时,该网站删除了 cookie。 symfony 日志如下所示:

[Application] Oct 21 14:14:12 |DEBUG  | SECURI Remember-me cookie detected. 
[Application] Oct 21 14:14:12 |INFO   | SECURI User for remember-me cookie not found. 
[Application] Oct 21 14:14:12 |DEBUG  | DOCTRI SELECT t0.id AS id_1, t0.email AS email_2, t0.roles AS roles_3, t0.password AS password_4, t0.is_verified AS is_verified_5, t0.pending_surfpoints AS pending_surfpoints_6, t0.surfpoints_total AS surfpoints_total_7, t0.balance AS balance_8, t0.username AS username_9, t0.ref_earning AS ref_earning_10, t0.ref_id AS ref_id_11 FROM user t0 WHERE t0.email = ? LIMIT 1 0="myUsername"
[Application] Oct 21 14:14:12 |DEBUG  | SECURI Clearing remember-me cookie. name="REMEMBERME"

我将用户登录配置为使用电子邮件和用户名(我的更改如下所述)。我认为现在的问题是,记住我的 cookie 正在我的数据库的用户名部分中搜索用户名。

我更改了 UserAuthentificatorAuthenticator.php 中的 getUser 函数以查找电子邮件,如果用户名失败:

public function getUser($credentials, UserProviderInterface $userProvider)
    {
        $token = new CsrfToken('authenticate', $credentials['csrf_token']);
        if (!$this->csrfTokenManager->isTokenValid($token)) {
            throw new InvalidCsrfTokenException();
        }

        $user = $this->entityManager->getRepository(User::class)->findOneBy(['email' => $credentials['email']]);


        if (!$user) {
            //Email could not be found - try username
            $user = $this->entityManager->getRepository(User::class)->findOneBy(['username' => $credentials['email']]);
            if (!$user){
                // fail authentication with a custom error
                throw new CustomUserMessageAuthenticationException('Email/Username konnten nicht gefunden werden.');
            }

        }
        if (!$user->isVerified()){
            throw new CustomUserMessageAuthenticationException('Der Account wurde noch nicht aktiviert.');

        }

        return $user;
    }

我现在在哪里可以调整 cookie 验证器以使其工作?

编辑: 我的 security.yaml

security:
    encoders:
        App\Entity\User:
            algorithm: auto

    # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
    providers:
        # used to reload user from session & other features (e.g. switch_user)
        app_user_provider:
            entity:
                class: App\Entity\User
                property: email

    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            anonymous: true
            lazy: true
            provider: app_user_provider
            guard:
                authenticators:
                    - App\Security\UserAuthentificatorAuthenticator
            logout:
                path: app_logout
                # where to redirect after logout
                target: app_default_start
            remember_me:
                secret:   '%kernel.secret%'
                lifetime: 604800 # 1 week in seconds
                path:     /

你现在使用的built-inEntityUserProvider根据配置中指定的属性查找User对象。记住我功能使用 Provider 来查找用户,因为您的用户可以使用 emailusername 登录,当仅通过 email 查找时,找不到默认用户。您应该将查找逻辑移出 Authenticator 并移至 UserProvider.

将以下函数添加到您的 UserRepository 并使其成为 implement UserLoaderInterface:

public function loadUserByUsername($identifier)
{
    $qb = $this->createQueryBuilder('u');
    return $qb->where('u.username = :identifier')
        ->orWhere('u.email = :identifier')
        ->setParameter('identifier', $identifier)
        ->getQuery()
        ->getOneOrNullResult();
}

security.yaml 中删除 property:

app_user_provider:
    entity:
        class: App\Entity\User

更改您的身份验证器:

$token = new CsrfToken('authenticate', $credentials['csrf_token']);
if (!$this->csrfTokenManager->isTokenValid($token)) {
    throw new InvalidCsrfTokenException();
}

$user = $userProvider->loadUserByUsername($credentials['email']);

if (!$user) {
    throw new CustomUserMessageAuthenticationException('Email/Username konnten nicht gefunden werden.');
}

if (!$user->isVerified()){
    throw new CustomUserMessageAuthenticationException('Der Account wurde noch nicht aktiviert.');
}

return $user;