src/Security/FacebookAuthenticator.php line 20

  1. <?php
  2. namespace App\Security;
  3. use App\Entity\User// your user entity
  4. use App\IlaveU\ShopBundle\Entity\Customer\Customer;
  5. use Doctrine\ORM\EntityManagerInterface;
  6. use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
  7. use KnpU\OAuth2ClientBundle\Security\Authenticator\OAuth2Authenticator;
  8. use Symfony\Component\HttpFoundation\RedirectResponse;
  9. use Symfony\Component\HttpFoundation\Request;
  10. use Symfony\Component\HttpFoundation\Response;
  11. use Symfony\Component\Routing\RouterInterface;
  12. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  13. use Symfony\Component\Security\Core\Exception\AuthenticationException;
  14. use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
  15. use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
  16. use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
  17. use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface;
  18. class FacebookAuthenticator extends OAuth2Authenticator implements
  19.     AuthenticationEntrypointInterface
  20. {
  21.     private $clientRegistry;
  22.     private $entityManager;
  23.     private $router;
  24.     public function __construct(
  25.         ClientRegistry $clientRegistry,
  26.         EntityManagerInterface $entityManager,
  27.         RouterInterface $router
  28.     ) {
  29.         $this->clientRegistry $clientRegistry;
  30.         $this->entityManager $entityManager;
  31.         $this->router $router;
  32.     }
  33.     public function supports(Request $request): ?bool
  34.     {
  35.         // continue ONLY if the current ROUTE matches the check ROUTE
  36.         return $request->attributes->get('_route') === 'connect_facebook_check';
  37.     }
  38.     public function authenticate(Request $request): Passport
  39.     {
  40.         $client $this->clientRegistry->getClient('facebook_main');
  41.         $accessToken $this->fetchAccessToken($client);
  42.         return new SelfValidatingPassport(
  43.             new UserBadge($accessToken->getToken(), function () use (
  44.                 $accessToken,
  45.                 $client
  46.             ) {
  47.                 /** @var FacebookUser $facebookUser */
  48.                 $facebookUser $client->fetchUserFromToken($accessToken);
  49.                 $email $facebookUser->getEmail();
  50.                 // 1) have they logged in with Facebook before? Easy!
  51.                 $existingUser $this->entityManager
  52.                     ->getRepository(User::class)
  53.                     ->findOneBy(['facebookId' => $facebookUser->getId()]);
  54.                 //User doesnt exist, we create it !
  55.                 if (!$existingUser) {
  56.                     if (!$email) {
  57.                         $emailDomain 'example.com';
  58.                         $email uniqid() . '@' $emailDomain;
  59.                     }
  60.                     $existingUser = new User();
  61.                     $existingUser->setUsername($email);
  62.                     $existingUser->setPassword($facebookUser->getId());
  63.                     $existingUser->setRoles(["ROLE_CUSTOMER"]);
  64.                     $existingUser->setFacebookId($facebookUser->getId());
  65.                     //Customer
  66.                 }
  67.                 $existingCustomer $this->entityManager
  68.                     ->getRepository(Customer::class)
  69.                     ->findOneBy(['user' => $existingUser]);
  70.                 if (!$existingCustomer or !$existingCustomer->getUser()) {
  71.                     $existingCustomer = new Customer();
  72.                     $existingCustomer->setEmail($email);
  73.                     $existingCustomer->setPhone('060000000000');
  74.                     $existingCustomer->setAddress('');
  75.                 }
  76.                 $existingCustomer->setFirstName($facebookUser->getFirstName());
  77.                 $existingCustomer->setLastName($facebookUser->getLastName());
  78.                 $existingCustomer->setUser($existingUser);
  79.                 $existingUser->setAvatar($facebookUser->getPictureUrl());
  80.                 $this->entityManager->persist($existingCustomer);
  81.                 $this->entityManager->persist($existingUser);
  82.                 $this->entityManager->flush();
  83.                 return $existingUser;
  84.             })
  85.         );
  86.     }
  87.     public function onAuthenticationSuccess(
  88.         Request $request,
  89.         TokenInterface $token,
  90.         string $firewallName
  91.     ): ?Response {
  92.         // change "app_homepage" to some route in your app
  93.         $targetUrl $this->router->generate(
  94.             'connect_facebook_after_connexion'
  95.         );
  96.         return new RedirectResponse($targetUrl);
  97.         // or, on success, let the request continue to be handled by the controller
  98.         //return null;
  99.     }
  100.     public function onAuthenticationFailure(
  101.         Request $request,
  102.         AuthenticationException $exception
  103.     ): ?Response {
  104.         $message strtr(
  105.             $exception->getMessageKey(),
  106.             $exception->getMessageData()
  107.         );
  108.         return new Response($messageResponse::HTTP_FORBIDDEN);
  109.     }
  110.     /**
  111.      * Called when authentication is needed, but it's not sent.
  112.      * This redirects to the 'login'.
  113.      */
  114.     public function start(
  115.         Request $request,
  116.         AuthenticationException $authException null
  117.     ): Response {
  118.         return new RedirectResponse(
  119.             '/connect/'// might be the site, where users choose their oauth provider
  120.             Response::HTTP_TEMPORARY_REDIRECT
  121.         );
  122.     }
  123. }