Symfony 使用 hwi/oauth-bundle 實現第三方登陸

  hwi/oauth-bundle插件官方文檔只簡單給出了登陸示例,實際工做中每每須要對獲取到的用戶信息進行存庫處理。那如何來處理呢,下面給出我在項目中處理步驟但願能幫助到你們。html

  首先建立hwi/oauth-bundle用戶提供程序,此類必須繼承並實現接口 OAuthAwareUserProviderInterface 。session

class OauthUserProvider extends OAuthAwareUserProviderInterface
{
    public function loadUserByOAuthUserResponse(UserResponseInterface $response)
    {
        $resourceOwnerName = $response->getResourceOwner()->getName();

        if (!isset($this->properties[$resourceOwnerName])) {
            throw new \RuntimeException(sprintf("No property defined for entity for resource owner '%s'.", $resourceOwnerName));
        }

        $username = $response->getUsername();

        switch ($resourceOwnerName) {
            case 'wechat':
                $user = $this->findByWeChat($respnse);
                break;
            case 'weibo':
                $user = $this->findUserByWeiBo($response);
                break;
        }

        if (null === $username || null == $user) {
            throw new AccountNotLinkedException(sprintf("User '%s' not found.", $username));
        }

        return $user;
    }

    protected function findByWeChat(UserResponseInterface $response)
    {
        // 參考 findUserByWeiBo
    }

    protected function findUserByWeiBo(UserResponseInterface $response)
    {
        $weiBoUserRepository = $this->em->getRepository('AppBundle:WeiBoUser');

        if (!$weiBoUser = $weiBoUserRepository->findOneBy(['weiBoId' => $response->getResponse()['idstr']])) {
            $weiBoUser = new WeiBoUser();
            $weiBoUser
                ->setWeiBoId($response->getResponse()['idstr']);
        }

        $weiBoUser
            ->setNickname($response->getNickname())
            ->setHeadImgUrl($response->getProfilePicture())
            ->setResponse($response->getResponse());
        $weiBoUserRepository->save($weiBoUser);

        if (!$weiBoUser->getUserId())
            return null;

        return $this->em
            ->getRepository('AppBundle:User')
            ->find($weiBoUser->getUserId());
    }

}

這個類的核心關鍵是 loadUserByOAuthUserResponse(UserResponseInterface $response) 方法。$response參數是一個 UserResponseInterface 實例,當用戶被從第三方登陸界面重定向回來時 $response便持有了用戶的第三方信息數據。$response->getResourceOwner()->getName()返回的是第三方登陸的配置名,具體見下面配置示例。此時咱們須要根據 $resourceOwnerName 參數 進行分別處理。在這裏我將查找和存庫在一個方法處理了,見 findUserByWeiBo(UserResponseInterface $response),具體想要存什麼數據,你能夠根據本身業務來處理 接口返回的原始數據可經過 $response->getResponse() 方法得到。當查找不到用戶時必定要拋出 AccountNotLinkedException 異常,以使 HWI\Bundle\OAuthBundle\Controller\ConnectController 控制器的 connectAction 方法來處理。至此第三方用戶數據存庫就處理完成了。ide

  接下來即是你的綁定業務流程實現。咱們新建控制器 ConnectController 並繼承自HWI\Bundle\OAuthBundle\Controller\ConnectController,覆寫其中registerAction 方法以實現咱們本身的註冊。this

use HWI\Bundle\OAuthBundle\Controller\ConnectController as HwiConnectController;

class ConnectController extends HwiConnectController 
{
/**
     * Shows a registration form if there is no user logged in and connecting
     * is enabled.
     *
     * @param Request $request a request
     * @param string  $key     key used for retrieving the right information for the registration form
     *
     * @return Response
     *
     * @throws NotFoundHttpException if `connect` functionality was not enabled
     * @throws AccessDeniedException if any user is authenticated
     * @throws \Exception
     */
    public function registrationAction(Request $request, $key)
    {
        $connect = $this->container->getParameter('hwi_oauth.connect');
        if (!$connect) {
            throw new NotFoundHttpException();
        }

        $hasUser = $this->isGranted('IS_AUTHENTICATED_REMEMBERED');
        if ($hasUser) {
            throw new AccessDeniedException('Cannot connect already registered account.');
        }

        $session = $request->getSession();
        $error = $session->get('_hwi_oauth.registration_error.'.$key);
        $session->remove('_hwi_oauth.registration_error.'.$key);

        if (!$error instanceof AccountNotLinkedException || time() - $key > 300) {
            // todo: fix this
            throw new \Exception('Cannot register an account.', 0, $error instanceof \Exception ? $error : null);
        }

        $userInformation = $this
            ->getResourceOwnerByName($error->getResourceOwnerName())
            ->getUserInformation($error->getRawToken())
        ;

        // 建立註冊form
        // 處理POST請求並登陸


        // reset the error in the session
        $key = time();
        $session->set('_hwi_oauth.registration_error.'.$key, $error);

        return $this->render('HWIOAuthBundle:Connect:registration.html.'.$this->getTemplatingEngine(), array(
            'key' => $key,
            'form' => $form->createView(),
            'userInformation' => $userInformation,
        ));
    }
}

最後就是修改配置啦。具體參考官方文檔,記住用戶提供程序改爲咱們本身的哦!spa

相關文章
相關標籤/搜索