OAuth Hwi Bundle,不同的社交网络
OAuth HwioBundle, different socialNetWork
我在 Symfony 中工作,它为不同的社交网络注册了 HWIOBundle。如果用户输入例如 LinkedIn 和一段时间 GitHub 我在数据库中有两个用户。谁知道怎么做是一个?
如果用户在两个社交账户中的邮箱相似,您可以使用邮箱字段来识别用户。您应该创建用户提供程序 class。如果在数据库中找不到提供社交令牌的用户,用户提供者将尝试通过电子邮件查找用户,并将指定社交网络的新社交令牌添加到现有用户实体。
代码示例。
services.xml
<service id="app.my_user_provider" class="AppBundle\Security\FOSUBUserProvider">
<argument type="service" id="user_manager"/>
<argument type="collection">
<argument key="facebook">%facebook_id%</argument>
<argument key="google">%google_id%</argument>
</argument>
<argument type="service" id="event_dispatcher"/>
</service>
security.yml, firewall section
oauth:
resource_owners:
facebook: "/login/check-facebook"
google: "/login/check-google"
login_path: /login
failure_path: /login
oauth_user_provider:
service: app.my_user_provider
src/AppBundle/Security/FOSUBUserProvider.php
<?php
namespace AppBundle\Security;
use HWI\Bundle\OAuthBundle\OAuth\Response\UserResponseInterface;
use HWI\Bundle\OAuthBundle\Security\Core\User\FOSUBUserProvider as BaseClass;
use Symfony\Component\Security\Core\User\UserInterface;
class FOSUBUserProvider extends BaseClass
{
/**
* {@inheritDoc}
*/
public function connect(UserInterface $user, UserResponseInterface $response)
{
$username = $response->getUsername();
$service = $response->getResourceOwner()->getName();
$setter = 'set' . ucfirst($service);
$setterId = $setter . 'Id';
$setterToken = $setter . 'AccessToken';
//disconnect previously connected user
if (null !== $previousUser = $this->userManager->findUserBy(array($this->getProperty($response) => $username))) {
$previousUser->$setterId(null);
$previousUser->$setterToken(null);
$this->userManager->updateUser($previousUser);
}
//connect current user
$user->$setterId($username);
$user->$setterToken($response->getAccessToken());
$this->userManager->updateUser($user);
}
/**
* {@inheritdoc}
*/
public function loadUserByOAuthUserResponse(UserResponseInterface $response)
{
$username = $response->getUsername();
$email = $response->getEmail();
$user = $this->userManager->findUserBy(array($this->getProperty($response) => $username));
if (null === $user) {
$user = $this->userManager->findUserByEmail($email);
$service = $response->getResourceOwner()->getName();
$setter = 'set' . ucfirst($service);
$setterId = $setter . 'Id';
$setterToken = $setter . 'AccessToken';
if (null === $user) {
$user = $this->userManager->createUser();
$user->$setterId($username);
$user->$setterToken($response->getAccessToken());
$user->setUsername($username);
$user->setEmail($email);
$user->setPassword($username);
$user->setEnabled(true);
$this->userManager->updateUser($user);
return $user;
} else {
$user->$setterId($username);
$user->$setterToken($response->getAccessToken());
$this->userManager->updateUser($user);
return $user;
}
}
//if user exists - go with the HWIOAuth way
$user = parent::loadUserByOAuthUserResponse($response);
$serviceName = $response->getResourceOwner()->getName();
$setter = 'set' . ucfirst($serviceName) . 'AccessToken';
//update access token
$user->$setter($response->getAccessToken());
return $user;
}
}
我在 Symfony 中工作,它为不同的社交网络注册了 HWIOBundle。如果用户输入例如 LinkedIn 和一段时间 GitHub 我在数据库中有两个用户。谁知道怎么做是一个?
如果用户在两个社交账户中的邮箱相似,您可以使用邮箱字段来识别用户。您应该创建用户提供程序 class。如果在数据库中找不到提供社交令牌的用户,用户提供者将尝试通过电子邮件查找用户,并将指定社交网络的新社交令牌添加到现有用户实体。
代码示例。
services.xml
<service id="app.my_user_provider" class="AppBundle\Security\FOSUBUserProvider">
<argument type="service" id="user_manager"/>
<argument type="collection">
<argument key="facebook">%facebook_id%</argument>
<argument key="google">%google_id%</argument>
</argument>
<argument type="service" id="event_dispatcher"/>
</service>
security.yml, firewall section
oauth:
resource_owners:
facebook: "/login/check-facebook"
google: "/login/check-google"
login_path: /login
failure_path: /login
oauth_user_provider:
service: app.my_user_provider
src/AppBundle/Security/FOSUBUserProvider.php
<?php
namespace AppBundle\Security;
use HWI\Bundle\OAuthBundle\OAuth\Response\UserResponseInterface;
use HWI\Bundle\OAuthBundle\Security\Core\User\FOSUBUserProvider as BaseClass;
use Symfony\Component\Security\Core\User\UserInterface;
class FOSUBUserProvider extends BaseClass
{
/**
* {@inheritDoc}
*/
public function connect(UserInterface $user, UserResponseInterface $response)
{
$username = $response->getUsername();
$service = $response->getResourceOwner()->getName();
$setter = 'set' . ucfirst($service);
$setterId = $setter . 'Id';
$setterToken = $setter . 'AccessToken';
//disconnect previously connected user
if (null !== $previousUser = $this->userManager->findUserBy(array($this->getProperty($response) => $username))) {
$previousUser->$setterId(null);
$previousUser->$setterToken(null);
$this->userManager->updateUser($previousUser);
}
//connect current user
$user->$setterId($username);
$user->$setterToken($response->getAccessToken());
$this->userManager->updateUser($user);
}
/**
* {@inheritdoc}
*/
public function loadUserByOAuthUserResponse(UserResponseInterface $response)
{
$username = $response->getUsername();
$email = $response->getEmail();
$user = $this->userManager->findUserBy(array($this->getProperty($response) => $username));
if (null === $user) {
$user = $this->userManager->findUserByEmail($email);
$service = $response->getResourceOwner()->getName();
$setter = 'set' . ucfirst($service);
$setterId = $setter . 'Id';
$setterToken = $setter . 'AccessToken';
if (null === $user) {
$user = $this->userManager->createUser();
$user->$setterId($username);
$user->$setterToken($response->getAccessToken());
$user->setUsername($username);
$user->setEmail($email);
$user->setPassword($username);
$user->setEnabled(true);
$this->userManager->updateUser($user);
return $user;
} else {
$user->$setterId($username);
$user->$setterToken($response->getAccessToken());
$this->userManager->updateUser($user);
return $user;
}
}
//if user exists - go with the HWIOAuth way
$user = parent::loadUserByOAuthUserResponse($response);
$serviceName = $response->getResourceOwner()->getName();
$setter = 'set' . ucfirst($serviceName) . 'AccessToken';
//update access token
$user->$setter($response->getAccessToken());
return $user;
}
}