我似乎无法让Hwioauthbundle在symfony3中使用我的自定义userbundle。我想在我的应用程序中使用googleoauth,用户可以使用google登录并使用注册表单。任何一种方法都会将用户存储在数据库中。注册表单本身效果很好,但在介绍hwioauthbundle时,事情对我来说不会有用。我遇到的一些问题包括:
我已经进行了大量搜索,但我似乎无法弄清楚这个问题。任何有关我错误甚至替代方面的帮助都将受到高度赞赏
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。我知道这段代码并不完美,但我觉得这不是我收到前面提到的问题的原因。
答案 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映射的自己的标识符。
错误,我希望我能够从其他线程获得解决方案。