HWIOAuthBundle和Custom UserBundle似乎无法协同工作

时间:2017-03-29 17:36:38

标签: php symfony security google-oauth symfony-3.2

我似乎无法让Hwioauthbundle在symfony3中使用我的自定义userbundle。我想在我的应用程序中使用googleoauth,用户可以使用google登录并使用注册表单。任何一种方法都会将用户存储在数据库中。注册表单本身效果很好,但在介绍hwioauthbundle时,事情对我来说不会有用。我遇到的一些问题包括:

  1. 在打开我的登录页面时,我会看到一个空白页面,其中包含文字" google"的链接,这与我预期的登录表单相反。但是,如果我将登录页面更改为除了接近"登录"之外的任何路径。和"登录",显示表格。
  2. 令人惊讶的是,该链接按我的意愿行事,即重定向到谷歌的权限页面,但在允许它继续之后,我得到了#34;发送HTTP请求时出错#34;消息。
  3. 打开网址" / login / check-google"我在请求中得到了一个" No oauth代码。"在之前的案例中,文字后跟相同的Google链接。
  4. 我已经进行了大量搜索,但我似乎无法弄清楚这个问题。任何有关我错误甚至替代方面的帮助都将受到高度赞赏

    providers:
            intersect_provider:
                entity:
                    class: UserBundle:User
                    property: username
    firewalls:
    
        # disables authentication for assets and the profiler, adapt it according to your needs
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
    
        main:
            anonymous: ~
            guard:
                authenticators:
                    - intersect.authenticator.form_login
                entry_point: intersect.authenticator.form_login
            form_login:
                provider: intersect_provider
                login_path: /login
                check_path: /login
            logout:
                path:   /signout
                target: /
            oauth:
                resource_owners:
                    google:             "/login/check-google"
                login_path: /
                use_forward:       false
                failure_path:      /login
    
                oauth_user_provider:
                    service: intersect.authenticator.oauth
    

    Security.yml文件

    hwi_oauth:
    firewall_names: [ "main" ]
    resource_owners:
        google:
            type: google
            client_id:  <clientid>
            client_secret:  <secret>
            scope: "email profile"
            options:
                access_type:  offline
                csrf: true
    

    config.yml文件

     <?php
    
    namespace Intersect\UserBundle\Security;
    
    use Symfony\Component\HttpFoundation\Request;
    use Symfony\Component\HttpFoundation\JsonResponse;
    use Symfony\Component\Security\Core\User\UserInterface;
    use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator;
    use Symfony\Component\Security\Guard\AbstractGuardAuthenticator;
    use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
    use Symfony\Component\Security\Core\Exception\AuthenticationException;
    use Symfony\Component\Security\Core\User\UserProviderInterface;
    use Doctrine\ORM\EntityManager;
    use Symfony\Component\Routing\RouterInterface;
    use Symfony\Component\Security\Core\Encoder\UserPasswordEncoder;
    use Symfony\Component\Security\Core\Security;
    
    class LoginFormAuthenticator extends AbstractFormLoginAuthenticator
    {
        private $em;
        private $passwordEncoder;
        private $router;
    
        public function __construct(EntityManager $em, RouterInterface $router, UserPasswordEncoder $passwordEncoder )
        {
            $this->passwordEncoder = $passwordEncoder;
            $this->em = $em;
            $this->router = $router;
        }
    
        public function getCredentials(Request $request)
        {
            $isLoginSubmit = $request->getPathInfo() == '/login' && $request->isMethod('POST');
            if(!$isLoginSubmit){
                return;
            }
            $username = $request->request->get('_username');
            $request->getSession()->set(Security::LAST_USERNAME, $username);
            $password = $request->request->get('_password');
    
            return [
                'username'=>$username,
                'password'=>$password
            ];
    
        }
    
        public function getUser($credentials, UserProviderInterface $userProvider)
        {
            $username=$credentials['username'];
            return $this->em->getRepository('UserBundle:User')->findByUsernameOrEmail($username);
    
        }
    
        public function checkCredentials($credentials, UserInterface $user)
        {
            $password=$credentials['password'];
            if ($this->passwordEncoder->isPasswordValid($user, $password)) {
                return true;
            }
            return false;
        }
    
        protected function getLoginUrl()
        {
            return $this->router->generate('intersect_login');
        }
    
        protected function getDefaultSuccessRedirectUrl()
        {
            return $this->router->generate('homepage');
        }
    
    }
    

    我的表单身份验证器:LoginFormAuthenticator.php

    parameters:
    #    parameter_name: value
    
    services:
    #    service_name:
    #        class: AppBundle\Directory\ClassName
    #        arguments: ["@another_service_name", "plain_value", "%parameter_name%"]
        intersect.authenticator.form_login:
            class: Intersect\UserBundle\Security\LoginFormAuthenticator
            autowire: true
            # autowire: true
    
        hwi_oauth.user.provider.entity:
            class: HWI\Bundle\OAuthBundle\Security\Core\User\OAuthUserProvider
    
        intersect.authenticator.oauth:
            class: Intersect\UserBundle\Security\OAuthProvider
            arguments:
                - '@session'
                - '@doctrine'
                - '@service_container'
    

    services.yml文件

    hwi_oauth_login:
    resource: "@HWIOAuthBundle/Resources/config/routing/login.xml"
    prefix:   /login
    
    hwi_oauth_redirect:
        resource: "@HWIOAuthBundle/Resources/config/routing/redirect.xml"
        prefix:   /login
    
    google_login:
        path: /login/check-google
    
    user:
        resource: "@UserBundle/Controller/"
        type:     annotation
        prefix:   /
    
    app:
        resource: "@AppBundle/Controller/"
        type:     annotation
    

    Routing.yml文件

    <?php
    
    namespace Intersect\UserBundle\Controller;
    
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
    use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
    use Symfony\Component\HttpFoundation\Request;
    use Intersect\UserBundle\Entity\User;
    
    class SecurityController extends Controller
    {
    
      /**
       * @Route("/login",name="intersect_login")
       */
       public function loginAction(){
         $helper = $this->get('security.authentication_utils');
    
         return $this->render('Intersect/login.html.twig',[
               'last_username' => $helper->getLastUsername(),
               'error' => $helper->getLastAuthenticationError(),
            ]
         );
    
       }
    
      /**
       * @Route("/signup",name="intersect_signup")
       */
      public function signupAction(Request $request)
      {
    
          $user = new User;
          $regform = $this->createForm('Intersect\UserBundle\Form\SignUpType', $user);
    
          $regform->handleRequest($request);
          if($regform->isSubmitted() && $regform->isValid()){
              $encoder = $this->container->get('security.password_encoder');
              $password = $encoder->encodePassword($user, $user->getPlainPassword());
              $user->setPassword($password);
    
              $em = $this->getDoctrine()->getManager();
              $em->persist($user);
              $em->flush();
    
              return $this->redirectToRoute('homepage');
          }
    
          return $this->render('Intersect/signup.html.twig',[
            'regform'=>$regform->createView()
          ]);
        }
    }
    

    SecurityController文件

    <?php
    namespace Intersect\UserBundle\Security;
    
    use HWI\Bundle\OAuthBundle\Security\Core\User\OAuthUserProvider;
    use HWI\Bundle\OAuthBundle\OAuth\Response\UserResponseInterface;
    use Symfony\Component\Security\Core\User\UserInterface;
    use Intersect\UserBundle\Entity\User;
    use Doctrine\ORM\EntityManager;
    use Symfony\Component\Security\Core\Security;
    
    class OAuthProvider extends OAuthUserProvider
    {
        protected $session, $doctrine, $admins;
    
        public function __construct($session, $doctrine, $service_container)
        {
            $this->session = $session;
            $this->doctrine = $doctrine;
            $this->container = $service_container;
        }
    
        public function loadUserByUsername($username)
        {
    
            $qb = $this->doctrine->getManager()->createQueryBuilder();
            $qb->select('u')
                ->from('UserBundle:User', 'u')
                ->where('u.googleId = :gid')
                ->setParameter('gid', $username)
                ->setMaxResults(1);
            $result = $qb->getQuery()->getResult();
    
            if (count($result)) {
                return $result[0];
            } else {
                return new User();
            }
        }
    
        public function saveOauthUserResponse(UserResponseInterface $response)
        {
          //data from google
          $google_Id=$response->$response->getUserName();
          $email=$response->getEmail();
          // $username = $response->getRealName();
          // $avatar = $response->getProfilePicture();
    
          //save googele data
          $this->session->set('email', $email);
          $this->session->set('username', $nickname);
          // $this->session->set('realname', $realname);
    
          $qb = $this->doctrine->getManager()->createQueryBuilder();
            $qb->select('u')
                ->from('UserBundle:User', 'u')
                ->where('u.oauth_Id = :gid')
                ->setParameter('gid', $google_Id)
                ->setMaxResults(1);
            $result = $qb->getQuery()->getResult();
    
            //add to database if doesn't exists
            if (!count($result)) {
                $user = new User();
                $user->setUsername($username);
                $user->setEmail($email);
                $user->setoauth_Id($oauth_Id);
                //$user->setRoles('ROLE_USER');
    
                //Set some wild random pass since its irrelevant, this is Google login
                  // $factory = $this->container->get('security.encoder_factory');
                  // $encoder = $factory->getEncoder($user);
                  // $password = $encoder->encodePassword(md5(uniqid()), $user->getSalt());
                  // $user->setPassword($password);
    
                $em = $this->doctrine->getManager();
                $em->persist($user);
                $em->flush();
            } else {
                $user = $result[0]; /* return User */
            }
            //set id
            $this->session->set('id', $user->getId());
    
            return $doctrine->findByUsernameOrEmail($response->getUsername());
    
        }
    }
    

    OauthProvider。我知道这段代码并不完美,但我觉得这不是我收到前面提到的问题的原因。

1 个答案:

答案 0 :(得分:1)

我想我已经解决了我之前提到过的问题,但我还没有完成整个事情。我是如何解决的

我将hwi_oauth_login前缀更改为

  

/连接

  

/登录

在Routing.yml

hwi_oauth_login:
    resource: "@HWIOAuthBundle/Resources/config/routing/login.xml"
    prefix:   /connect

然后在SecurityController.php

中为我的登录路由添加了正斜杠
/**
   * @Route("/login/",name="intersect_login")
   */
   public function loginAction(){
     $helper = $this->get('security.authentication_utils');

     return $this->render('Intersect/signin.html.twig',[
           'last_username' => $helper->getLastUsername(),
           'error' => $helper->getLastAuthenticationError(),
        ]
     );

   }

用于启动Google身份验证的网址是

  

/连接/&LT; \ resource_owner&GT;

其中&lt; \ resource_owner&gt;是&#34; google&#34;

的占位符

现在我得到了

  

您无法从EntityUserProvider刷新用户   包含标识符。用户对象必须使用它进行序列化   由Doctrine映射的自己的标识符。

错误,我希望我能够从其他线程获得解决方案。

相关问题