Symfony 4 记住我没有用户名无法工作

Symfony 4 Remember me not working without username

我们如何配置 Symfony 4 Remember me 功能以在创建 cookie 并将其存储在浏览器中时使用电子邮件而不是用户名(默认设置)?

我的问题是,通过在 S4 中使用电子邮件进行身份验证,cookie 是使用用户名而不是哈希中的电子邮件创建的,存储在浏览器中,但是当 S4 检查我的 cookie 以查看是否 IS_AUTHENTICATED_REMEMBERED是真的,它根据存储在数据库中的用户名进行检查,这没有意义。它应该根据电子邮件检查它。所以我的记住我功能不起作用。 如果我使用用户名登录,那么就可以了,但这不是我想要的,我希望我的用户使用他们的电子邮件地址登录。

我已经将登录配置为使用电子邮件而不是默认的用户名行为,但我不记得我是那样工作的。

我在 security.yaml

中尝试了以下方法
security:
    encoders:
        App\Entity\User:
            algorithm: bcrypt
    providers:
        user_provider:
            entity:
                class: App\Entity\User
                property: email
        in_memory: { memory: ~ }
        our_db_provider:
            entity:
                class: App\Entity\User
                property: email
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            pattern:    ^/
            http_basic: ~
            provider: our_db_provider
            anonymous: ~
            form_login:
                login_path: login
                check_path: login
                default_target_path: dashboard
                username_parameter: email
                password_parameter: password
                remember_me: true
            remember_me:
                secret:   '%kernel.secret%'
                lifetime: 31536000 # 1 week in seconds
                path: /
                domain: ~
                secure:   true
                name:     REMEMBERME
                remember_me_parameter: remember_me
                always_remember_me: true
            logout:
                path:  /logout
                target: /

但这不允许您参数化哪些字段 remember 用于生成存储在 cookie 中的哈希值。

如果您成功设置了登录/身份验证并且记得我使用的字段不同于用户名,请分享 :)

更新:我尝试使用以下服务行回答 Ahmed,但它不起作用:

App\Security\TokenBasedRememberMeServices:
      decorates: Symfony\Component\Security\Http\RememberMe\TokenBasedRememberMeServices

它说 You have requested a non-existent service "Symfony\Component\Security\Http\RememberMe\TokenBasedRememberMeServices”.

安全组件使用getUsername()getter构建token的问题https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Security/Http/RememberMe/TokenBasedRememberMeServices.php#L74

因此我们需要覆盖负责创建记住我 cookie 的服务,希望是 security.authentication.rememberme.services.simplehash.class

Firstable: 更新 onLoginSuccess 方法 L74 因此它使用电子邮件而不是用户名。

namespace App\Security;
...
class TokenBasedRememberMeServices extends AbstractRememberMeServices
{
    ....
    protected function onLoginSuccess(Request $request, Response $response, TokenInterface $token)
    {
      ...
        $value = $this->generateCookieValue(\get_class($user), $user->getEmail(), $expires, $user->getPassword());
      ...
    }
...

其次:将您的class注册为服务。

 App\Security\TokenBasedRememberMeServices:
     decorates: 'security.authentication.rememberme.services.simplehash.class'

或者您可以在 UserInterface 下流动合同 它定义和 returns 用于验证用户身份的用户名。在我们的例子中是 email 属性.

public function getUsername()
{
    return $this->email;
}

我没有足够的 SO 声誉来添加评论以回答问题,所以我写在这里。

而不是装饰服务:

security.authentication.rememberme.services.simplehash.class

装饰:

security.authentication.rememberme.services.simplehash

它适用于 Symfony 4.4