Symfony 4 Помни, я не работаю без имени пользователя - PullRequest
0 голосов
/ 07 января 2019

Как мы можем настроить функциональность Symfony 4 Запомнить меня, чтобы использовать электронную почту вместо имени пользователя (как установлено по умолчанию) при создании 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: /

но это не позволяет вам указать, какое поле запоминания используется для генерации хеша, хранящегося в cookie.

Если вам удалось настроить логин / аутентификацию и помните, что я работал с полем, отличным от имени пользователя, пожалуйста, поделитесь:)

ОБНОВЛЕНИЕ: Я попытался ответить Ахмеда со следующими строками об услугах, но он не работает:

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

сказано You have requested a non-existent service "Symfony\Component\Security\Http\RememberMe\TokenBasedRememberMeServices”.

1 Ответ

0 голосов
/ 07 января 2019

Проблема в том, что компонент безопасности использует getUsername() getter для построения токена 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());
      ...
    }
...

Второе: Зарегистрируйте свой класс как услугу.

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

Или вы можете передать контракт по UserInterface Он определяет и возвращает имя пользователя, используемое для аутентификации пользователя. В нашем случае это свойство email.

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