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

问题描述

我已将symfony 4配置为在用户选中复选框时设置“记住我” cookie。这可以正常工作。但是,当我重新启动浏览器并返回网站时,该网站删除了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:     /

解决方法

您正在使用的内置EntityUserProvider根据配置中指定的属性查找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;