目标:使用OAuth提供商制作身份验证系统(例如脸谱版)
解决方案:我安装并设置了HWIOAuthBundle,制作了自定义用户类,一切正常并经过身份验证。因此,在从oauth提供者安全层回调之后,请求提供者从数据库加载用户的loadUserByOAuthUserResponse方法......
问题:...但是当symfony尝试对用户进行身份验证时,它实际上正在调用loadUserByUsername方法的提供程序,并且只传递带有username的字符串。但Facebook誓言不返回用户名提供者,它实际上返回的资源用户名看起来像10152039919326906,并将NULL传递给用户名。当安全层要求loadUserByUsername时,它使用NULL参数调用它。
以下是dev的部分代码:
class OAuthUserProvider implements UserProviderInterface, OAuthAwareUserProviderInterface
{
protected $em;
protected $className;
protected $repository;
function __construct(ManagerRegistry $registry, $className) {
$this->em = $registry->getManager();
$this->repository = $this->em->getRepository($className);
$this->className = $className;
}
public function loadUserByOAuthUserResponse(UserResponseInterface $response)
{
$username = $response->getUsername();
$nickname = $response->getNickname();
$realname = $response->getRealName();
$email = $response->getEmail();
$resourceOwnerName = $response->getResourceOwner()->getName();
$user = $this->repository->findOneBy(
array('resource' => $resourceOwnerName, 'resourceUsername' => $username)
);
if (null === $user) {
$user = new $this->className;
$user->setUsername($nickname);
$user->setResourceUsername($username);
$user->setResource($resourceOwnerName);
$user->setRealname($realname);
$user->setEmail($email);
$user->setLastLogin(new \DateTime());
// facebook crutch
if (null == $user->getUsername()) {
$user->setUsername($username);
}
$this->em->persist($user);
$id = $this->em->flush();
}
if ($user) {
return $user;
}
}
public function loadUserByUsername($username) {
$user = $this->repository->findOneBy(array('username' => $username));
if (!$user) {
throw new UsernameNotFoundException(sprintf("User '%s' not found.", $username));
}
return $user;
}
所以,我想,我需要来crutch,如果username是NULL,将传递给loadUserByUsername电子邮件或其他字段,并且不仅在用户名字段中为搜索DB重写一点。
由于loadUserByUsername,有很多类似这样的情况可能会变得怪异。例如。 twitter誓言不返回电子邮件,但返回用户名。有没有办法重写loadByUsername调用的接口?