如何确保 Symfony UserBadge 始终接受不区分大小写的用户名?
How to make sure case insensitive usernames are always accepted by Symfony UserBadge?
我在我的 Symfony 5 项目中创建了一个自定义 AbstractAuthenticator
subclass,它可以处理 HTTP headers.
中包含的用户凭据
public function authenticate(Request $request): PassportInterface {
$userIdentifier = $this->getUserIdentifierFromRequest();
return new Passport(
new UserBadge($this->userIdentifier),
new CustomCredentials(
function ($credentials, UserInterface $user) {
...
},
$credentialFromRequest
)
);
}
这工作正常,当检查到无效的用户名时,UserBadge
抛出 UserNotFoundException
。
但是,我想知道为什么这个实现对给定的用户名不区分大小写?
我检查了 Symfony 代码,UserBadge
使用 EntityUserProvider
class 执行简单的 $repository->findOneBy([$this->property => $identifier])
(在我的例子中按字段 email
查找) .经过一些搜索,我找到了相关的答案,这表明 find...
是否区分大小写或不区分大小写很可能取决于底层数据库(在我的例子中是 MariaDB 10)。
有什么方法可以控制用户名查找是否区分大小写?
虽然不区分大小写的搜索在当前项目中很好,但我想确保它保持这种方式,无论我是否将项目移植到具有另一个底层数据库的另一台机器...
您可以创建 a custom User Provider.
然后在您的提供商中,只需在标识符上调用 strtolower()
,在标识符列上调用 LOWER()
。
一个相当简单的实现,假设您在用户提供程序上注入实体管理器。
public function loadUserByIdentifier(string $identifier): UserInterface
{
$user = $this->em->createQueryBuilder()
->select('u')
->from(YourUser::class, 'u')
->where('LOWER(u.username) = :username')
->setParameter('username', strtolower($identifier))
->setMaxResults(1)
->getQuery()
->getOneOrNullResult();
if (!$user instanceof YourUser::class) {
throw new UserNotFoundException('No user found for ' . $username);
}
return $user;
}
根据您的应用程序限制进行调整。您或许可以将查询本身移动到特定的实体存储库,并在那里创建查询,而不是提供程序。
我在我的 Symfony 5 项目中创建了一个自定义 AbstractAuthenticator
subclass,它可以处理 HTTP headers.
public function authenticate(Request $request): PassportInterface {
$userIdentifier = $this->getUserIdentifierFromRequest();
return new Passport(
new UserBadge($this->userIdentifier),
new CustomCredentials(
function ($credentials, UserInterface $user) {
...
},
$credentialFromRequest
)
);
}
这工作正常,当检查到无效的用户名时,UserBadge
抛出 UserNotFoundException
。
但是,我想知道为什么这个实现对给定的用户名不区分大小写?
我检查了 Symfony 代码,UserBadge
使用 EntityUserProvider
class 执行简单的 $repository->findOneBy([$this->property => $identifier])
(在我的例子中按字段 email
查找) .经过一些搜索,我找到了相关的答案,这表明 find...
是否区分大小写或不区分大小写很可能取决于底层数据库(在我的例子中是 MariaDB 10)。
有什么方法可以控制用户名查找是否区分大小写?
虽然不区分大小写的搜索在当前项目中很好,但我想确保它保持这种方式,无论我是否将项目移植到具有另一个底层数据库的另一台机器...
您可以创建 a custom User Provider.
然后在您的提供商中,只需在标识符上调用 strtolower()
,在标识符列上调用 LOWER()
。
一个相当简单的实现,假设您在用户提供程序上注入实体管理器。
public function loadUserByIdentifier(string $identifier): UserInterface
{
$user = $this->em->createQueryBuilder()
->select('u')
->from(YourUser::class, 'u')
->where('LOWER(u.username) = :username')
->setParameter('username', strtolower($identifier))
->setMaxResults(1)
->getQuery()
->getOneOrNullResult();
if (!$user instanceof YourUser::class) {
throw new UserNotFoundException('No user found for ' . $username);
}
return $user;
}
根据您的应用程序限制进行调整。您或许可以将查询本身移动到特定的实体存储库,并在那里创建查询,而不是提供程序。