您需要修改从Symfony文档中引用的代码,使其符合您的需求。事实上,它只允许通过电子邮件登录,但您需要额外添加用户名的可能性。
首先修改登录表单以允许使用用户名。因此,在教程的示例中,我们需要将类型和名称更改为以下内容:
<label for="inputEmailOrUsername">Email or Username</label>
<input type="text" value="{{ last_username }}" name="email_or_username" id="inputEmailOrUsername" class="form-control" required autofocus>
下一个是LoginFormAuthenticator(或它为您调用的任何东西)。修改
authenticate
方法来适应登录表单中的更改
public function getCredentials(Request $request)
{
$credentials = [
'email_or_username' => $request->request->get('email_or_username'),
'password' => $request->request->get('password'),
'csrf_token' => $request->request->get('_csrf_token'),
];
...
}
并修改
getUser
方法来查找电子邮件或用户名:
public function getUser($credentials, UserProviderInterface $userProvider): ?User
{
...
$user = $this->entityManager->getRepository(User::class)->findByEmailOrUsername($credentials['email_or_username']);
// ...
}
正如你所看到的,我已经更换了
findOneBy
使用不存在的方法调用存储库
findByEmailOrUsername
。继续在UserRepository类中创建此方法,使其类似于以下内容:
public function findByEmailOrUsername(string $emailOrUsername)
{
return $this->createQueryBuilder('u')
->where('u.email = :emailOrUsername')
->orWhere('u.username = :emailOrUsername')
->setParameter('emailOrUsername', $emailOrUsername)
->getQuery()
->getOneOrNullResult();
}
这应该是代码的通用工作原型,以便使用用户名或电子邮件地址登录。请自行验证登录表单输入字段。
更新
-
以适应最新的Symfony5 Authenticator更改
:
供参考:
Using the new Authenticator-based security
而不是使用
getCredentials
和
getUser
方法(它们已不存在),您应该使用
证明…是真实的
方法,通过将UserLoader作为第二个参数提供给UserBadge类来满足您的需求。
public function authenticate(Request $request): PassportInterface
{
$emailOrUsername = $request->request->get('email_or_username');
// ... get the rest of the parameters from the input bag
// ... validate no parameter is empty
return new Passport(
new UserBadge($emailOrUsername, function ($userIdentifier) {
return $this->userRepository->findByEmailOrUsername($userIdentifier);
}),
// ... rest of the parameters
);
}