На моем сайте я хочу, чтобы пользователь мог зарегистрироваться или войти через Facebook, Google или через базовую форму.Моя регистрация в Google работает отлично, но пользователь не может выбрать свое имя пользователя (проблема в том, что имя пользователя должно быть уникальным на моем сайте).
Как я могу перенаправить пользователя в форму после нажатия «Зарегистрироваться в Google»?
Я пытался перенаправить пользователя, когда я проверял, существует ли он уже, но я получил сообщение об ошибке типа «Вы не можете обновить пользователя из EntityUserProvider, который не содержит идентификатора. Объект пользователя должен быть сериализован сего собственный идентификатор, сопоставленный с Doctrine. "Это первый раз, когда я использую Oauth.
Вот мой GoogleAuthenticator
class GoogleAuthenticator extends SocialAuthenticator
{
use TargetPathTrait;
private $urlGenerator;
private $om;
public function __construct(ClientRegistry $clientRegistry, EntityManagerInterface $em, RouterInterface $router,UrlGeneratorInterface $urlGenerator, ObjectManager $om)
{
$this->clientRegistry = $clientRegistry;
$this->em = $em;
$this->router = $router;
$this->urlGenerator = $urlGenerator;
$this->om = $om;
}
public function supports(Request $request)
{
return $request->getPathInfo() == '/connect/google/check' && $request->isMethod('GET');
}
public function getCredentials(Request $request)
{
return $this->fetchAccessToken($this->getGoogleClient());
}
public function getUser($credentials, UserProviderInterface $userProvider)
{
/** @var GoogleUser $googleUser */
$googleUser = $this->getGoogleClient()
->fetchUserFromToken($credentials);
$email = $googleUser->getEmail();
$user = $this->em->getRepository('App:User')
->findOneBy(['email' => $email]);
if (!$user) {
$user = new User();
$user->setEmail($googleUser->getEmail());
if ($this->em->getRepository('App:User')
->findOneBy(['username' => $googleUser->getFirstName()])){
$user->setUsername($googleUser->getFirstName() . random_int(0,10));
} else {
$user->setUsername($googleUser->getFirstName());
}
$user->setIsBanned(0);
$user->setIsActive(0);
$user->setRoles(array('ROLE_USER'));
$user->setCreatedAt(new \DateTime(date('Y-m-d H:i:s')));
$this->em->persist($user);
$this->em->flush();
}
return $user;
}
/**
* @return \KnpU\OAuth2ClientBundle\Client\OAuth2Client
*/
private function getGoogleClient()
{
return $this->clientRegistry
->getClient('google');
}
/**
* Returns a response that directs the user to authenticate.
*
* This is called when an anonymous request accesses a resource that
* requires authentication. The job of this method is to return some
* response that "helps" the user start into the authentication process.
*
* Examples:
* A) For a form login, you might redirect to the login page
* return new RedirectResponse('/login');
* B) For an API token authentication system, you return a 401 response
* return new Response('Auth header required', 401);
*
* @param Request $request The request that resulted in an AuthenticationException
* @param \Symfony\Component\Security\Core\Exception\AuthenticationException $authException The exception that started the authentication process
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function start(Request $request, \Symfony\Component\Security\Core\Exception\AuthenticationException $authException = null)
{
return new RedirectResponse('/login');
}
/**
* Called when authentication executed, but failed (e.g. wrong username password).
*
* This should return the Response sent back to the user, like a
* RedirectResponse to the login page or a 403 response.
*
* If you return null, the request will continue, but the user will
* not be authenticated. This is probably not what you want to do.
*
* @param Request $request
* @param \Symfony\Component\Security\Core\Exception\AuthenticationException $exception
*
* @return \Symfony\Component\HttpFoundation\Response|null
*/
public function onAuthenticationFailure(Request $request, \Symfony\Component\Security\Core\Exception\AuthenticationException $exception)
{
// TODO: Implement onAuthenticationFailure() method.
}
/**
* Called when authentication executed and was successful!
*
* This should return the Response sent back to the user, like a
* RedirectResponse to the last page they visited.
*
* If you return null, the current request will continue, and the user
* will be authenticated. This makes sense, for example, with an API.
*
* @param Request $request
* @param \Symfony\Component\Security\Core\Authentication\Token\TokenInterface $token
* @param string $providerKey The provider (i.e. firewall) key
*
* @return void
*/
public function onAuthenticationSuccess(Request $request, \Symfony\Component\Security\Core\Authentication\Token\TokenInterface $token, $providerKey)
{
if ($targetPath = $this->getTargetPath($request->getSession(), $providerKey)) {
return new RedirectResponse($targetPath);
}
$user = $token->getUser();
$user->setLastLogin(new \DateTime);
$this->om->flush();
return new RedirectResponse($this->urlGenerator->generate('home'));
}
}
И мой GoogleController
class GoogleController extends AbstractController
{
/**
* Link to this controller to start the "connect" process
*
* @Route("/connect/google", name="connect_google")
* @param ClientRegistry $clientRegistry
* @return \Symfony\Component\HttpFoundation\RedirectResponse
*/
public function connectAction(ClientRegistry $clientRegistry)
{
return $clientRegistry
->getClient('google')
->redirect();
}
/**
* Facebook redirects to back here afterwards
*
* @Route("/connect/google/check", name="connect_google_check")
* @param Request $request
* @return JsonResponse|\Symfony\Component\HttpFoundation\RedirectResponse
*/
public function connectCheckAction(Request $request)
{
if (!$this->getUser()) {
return new JsonResponse(array('status' => false, 'message' => "User not found!"));
} else {
return $this->redirectToRoute('home');
}
}
}
Я не имею ни малейшего представления о том, где я должен разместить код для перенаправления пользователя в форму.Я хотел бы, чтобы пользователь выбрал свое имя пользователя и нажал «Зарегистрироваться», например, как stackoverflow.