src/Security/GoogleAuthenticator.php line 20

  1. <?php
  2. namespace App\Security;
  3. use App\Entity\User// your user entity
  4. use Doctrine\ORM\EntityManagerInterface;
  5. use Symfony\Component\HttpFoundation\Request;
  6. use Symfony\Component\HttpFoundation\Response;
  7. use Symfony\Component\Routing\RouterInterface;
  8. use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
  9. use Symfony\Component\HttpFoundation\RedirectResponse;
  10. use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
  11. use Symfony\Component\Security\Core\Exception\AuthenticationException;
  12. use KnpU\OAuth2ClientBundle\Security\Authenticator\OAuth2Authenticator;
  13. use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
  14. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  15. use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
  16. use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
  17. class GoogleAuthenticator extends OAuth2Authenticator
  18. {
  19.     private $clientRegistry;
  20.     private $entityManager;
  21.     private $router;
  22.     public function __construct(ClientRegistry $clientRegistryEntityManagerInterface $entityManagerRouterInterface $router)
  23.     {
  24.         $this->clientRegistry $clientRegistry;
  25.         $this->entityManager $entityManager;
  26.         $this->router $router;
  27.     }
  28.     public function supports(Request $request): ?bool
  29.     {
  30.         // continue ONLY if the current ROUTE matches the check ROUTE
  31.         return $request->attributes->get('_route') === 'connect_google_check';
  32.     }
  33.     public function authenticate(Request $request): Passport
  34.     {
  35.         $client $this->clientRegistry->getClient('google');
  36.         $accessToken $this->fetchAccessToken($client);
  37.         return new SelfValidatingPassport(
  38.             new UserBadge($accessToken->getToken(), function () use ($accessToken$client) {
  39.                 /** @var GoogleUser $googleUser */
  40.                 $googleUser $client->fetchUserFromToken($accessToken);
  41.                 $email $googleUser->getEmail();
  42.                 // 1) have they logged in with Google before? Easy!
  43.                 $existingUser $this->entityManager->getRepository(User::class)->findOneBy(['google_id' => $googleUser->getId()]);
  44.                 if ($existingUser) {
  45.                     return $existingUser;
  46.                 }
  47.                 // 2) do we have a matching user by email?
  48.                 $user $this->entityManager->getRepository(User::class)->findOneBy(['email' => $email]);
  49.                 if (is_null($user)) {
  50.                     $user = new User();
  51.                     $email $googleUser->getEmail();
  52.                     $firstName $googleUser->getFirstName();
  53.                     $lastName $googleUser->getLastName();
  54.                     $avatar $googleUser->getAvatar();
  55.                     $user->setPassword('abdomgh');
  56.                     $user->setEmail($email);
  57.                     $user->setIsVerified(true);
  58.                     $user->setFirstName($firstName);
  59.                     $user->setLastName($lastName);
  60.                     $user->setPhoto($avatar);
  61.                 }
  62.                 // 3) Maybe you just want to "register" them by creating
  63.                 // a User object
  64.                 $user->setGoogleId($googleUser->getId());
  65.                 $this->entityManager->persist($user);
  66.                 $this->entityManager->flush();
  67.                 return $user;
  68.             })
  69.         );
  70.     }
  71.     public function onAuthenticationSuccess(Request $requestTokenInterface $tokenstring $firewallName): ?Response
  72.     {
  73.         // change "app_homepage" to some route in your app
  74.         $targetUrl $this->router->generate('app_main');
  75.         return new RedirectResponse($targetUrl);
  76.         // or, on success, let the request continue to be handled by the controller
  77.         //return null;
  78.     }
  79.     public function onAuthenticationFailure(Request $requestAuthenticationException $exception): ?Response
  80.     {
  81.         $message strtr($exception->getMessageKey(), $exception->getMessageData());
  82.         return new Response($messageResponse::HTTP_FORBIDDEN);
  83.     }
  84. }