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
来查找用户,因为您的用户可以使用 email
或 username
登录,当仅通过 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;
我已将 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
来查找用户,因为您的用户可以使用 email
或 username
登录,当仅通过 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;