Catégories
Étiquettes
API Audit Auditor Bundle Authentification Bulma Cache Castor ChatGPT Développement Développement Web DevOps Docker Documentation Facebook FrankenPHP Fullstack Gestion de processus GitHub Google JavaScript Linux Linux Mint MacBook Pro macOS Makefile OAuth2 OpenAI Optimisation Performance PHP PHPUnit Pop!_OS Profil README Setup SQL Svelte Symfony Symfony Lock Technologie Tutoriel Verrouillage Web Development Workflow
354 mots
2 minutes
Authentification avec Google dans Symfony 6
Dans cet article, nous allons voir comment se connecter à un site via vos identifiants Google ou Facebook, etc. (voir la liste complète ici). Nous partirons du principe que cette méthode sera exclusive (pas de mot de passe).
Création de l’entité User
Voici à quoi ressemble l’entité User utilisée :
#[ORM\Entity(repositoryClass: UserRepository::class)]
#[ORM\Table(name: '`user`')]
class User implements UserInterface
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private $id;
#[ORM\Column(type: 'string', length: 180, unique: true)]
private $email;
#[ORM\Column(type: 'json')]
private $roles = [];
#[ORM\Column(type: 'string', length: 255)]
private $googleId;
#[ORM\Column(type: 'text', nullable: true)]
private $avatar;
#[ORM\Column(type: 'string', length: 255)]
private $hostedDomain;
}
Installation des dépendances
Ajoutez les dépendances nécessaires :
composer require knpuniversity/oauth2-client-bundle
composer require league/oauth2-google
Configuration
Ajoutez la configuration suivante dans config/packages/knpu_oauth2_client.yaml :
knpu_oauth2_client:
clients:
google:
type: google
client_id: '%env(resolve:GOOGLE_CLIENT_ID)%'
client_secret: '%env(resolve:GOOGLE_CLIENT_SECRET)%'
redirect_route: connect_google_check
redirect_params: {}
Ensuite, ajoutez les variables GOOGLE_CLIENT_ID et GOOGLE_CLIENT_SECRET dans votre fichier .env.
Création du contrôleur Google
Créez un contrôleur pour gérer la connexion :
<?php
namespace App\Controller;
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
class GoogleController extends AbstractController
{
#[Route('/connect/google', name: 'connect_google')]
public function connectAction(ClientRegistry $clientRegistry)
{
return $clientRegistry->getClient('google')->redirect([], []);
}
#[Route('/connect/google/check', name: 'connect_google_check')]
public function connectCheckAction(Request $request)
{
// Méthode vide pour authentifier via un guard
}
}
Authentification avec OAuth2Authenticator
Créez une classe d’authentification :
<?php
namespace App\Security;
use App\Entity\User;
use League\OAuth2\Client\Provider\GoogleUser;
use Doctrine\ORM\EntityManagerInterface;
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
use KnpU\OAuth2ClientBundle\Security\Authenticator\OAuth2Authenticator;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
class GoogleAuthenticator extends OAuth2Authenticator
{
private ClientRegistry $clientRegistry;
private EntityManagerInterface $entityManager;
private RouterInterface $router;
public function __construct(ClientRegistry $clientRegistry, EntityManagerInterface $entityManager, RouterInterface $router)
{
$this->clientRegistry = $clientRegistry;
$this->entityManager = $entityManager;
$this->router = $router;
}
public function supports(Request $request): ?bool
{
return $request->attributes->get('_route') === 'connect_google_check';
}
public function authenticate(Request $request): Passport
{
$client = $this->clientRegistry->getClient('google');
$accessToken = $this->fetchAccessToken($client);
return new SelfValidatingPassport(
new UserBadge($accessToken->getToken(), function () use ($accessToken, $client) {
$googleUser = $client->fetchUserFromToken($accessToken);
$email = $googleUser->getEmail();
$existingUser = $this->entityManager->getRepository(User::class)->findOneBy(['googleId' => $googleUser->getId()]);
if (!$existingUser) {
$existingUser = new User();
$existingUser->setEmail($email);
$existingUser->setGoogleId($googleUser->getId());
$existingUser->setHostedDomain($googleUser->getHostedDomain());
$this->entityManager->persist($existingUser);
}
$existingUser->setAvatar($googleUser->getAvatar());
$this->entityManager->flush();
return $existingUser;
})
);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
return new Response('Connexion réussie.', Response::HTTP_OK);
}
}
Conclusion
Et voilà ! Vous pouvez maintenant accéder à /connect/google pour vous connecter via Google et être authentifié dans votre application.
