zoukankan      html  css  js  c++  java
  • Symfony 使用 hwi/oauth-bundle 实现第三方登录

      hwi/oauth-bundle插件官方文档只简单给出了登录示例,实际工作中往往需要对获取到的用户信息进行存库处理。那如何来处理呢,下面给出我在项目中处理步骤希望能帮助到大家。

      首先创建hwi/oauth-bundle用户提供程序,此类必须继承并实现接口 OAuthAwareUserProviderInterface 。

    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 异常,以使 HWIBundleOAuthBundleControllerConnectController 控制器的 connectAction 方法来处理。至此第三方用户数据存库就处理完成了。

      接下来便是你的绑定业务流程实现。我们新建控制器 ConnectController 并继承自HWIBundleOAuthBundleControllerConnectController,覆写其中registerAction 方法以实现我们自己的注册。

    use HWIBundleOAuthBundleControllerConnectController 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,
            ));
        }
    }

    最后就是修改配置啦。具体参考官方文档,记住用户提供程序改成我们自己的哦!

  • 相关阅读:
    【python cookbook】找出序列中出现次数最多的元素
    2018/1/21 Netty通过解码处理器和编码处理器来发送接收POJO,Zookeeper深入学习
    读《风雨20年》小感
    两个知识点的回顾(const指针和动态链接库函数dlopen)
    小试牛刀
    chmod,chown和chgrp的区别
    node.js中使用node-schedule实现定时任务
    在 Node.js 上调用 WCF Web 服务
    nodejs发起HTTPS请求并获取数据
    openstack 之~云计算介绍
  • 原文地址:https://www.cnblogs.com/mickeyooo/p/9547666.html
Copyright © 2011-2022 走看看