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;
    }
}