Integrating Google login into a Symfony app can be done cleanly using OAuth2 via the knpuniversity/oauth2-client-bundle.

Here's a step-by-step outline to implement "Login with Google" in your Symfony app:


✅ 1. Set Up Google OAuth Credentials

Go to the Google Cloud Console:

  • Create a project.

  • Go to APIs & Services > Credentials.

  • Create OAuth 2.0 Client ID (choose "Web Application").

  • Add Authorized redirect URI:

    https://your-domain.com/connect/google/check
    

    Or for dev:

    https://localhost:8000/connect/google/check
    

Copy the Client ID and Client Secret.


✅ 2. Install Required Symfony Packages

composer require knpuniversity/oauth2-client-bundle league/oauth2-google

This installs:

  • KnpUOAuth2ClientBundle (manages OAuth2 clients)
  • Google provider for OAuth2

✅ 3. Configure the Bundle

In config/packages/knpu_oauth2_client.yaml:

knpu_oauth2_client:
    clients:
        google:
            type: google
            client_id: '%env(OAUTH_GOOGLE_CLIENT_ID)%'
            client_secret: '%env(OAUTH_GOOGLE_CLIENT_SECRET)%'
            redirect_route: connect_google_check
            redirect_params: {}

In .env or better in .env.local:

OAUTH_GOOGLE_CLIENT_ID=your_google_client_id
OAUTH_GOOGLE_CLIENT_SECRET=your_google_client_secret

✅ 4. Create a Route to Start Google Login

In your controller:

// src/Controller/ConnectController.php

use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Annotation\Route;

class ConnectController extends AbstractController
{
    #[Route('/connect/google', name: 'connect_google_start')]
    public function connect(ClientRegistry $clientRegistry): RedirectResponse
    {
        return $clientRegistry
            ->getClient('google')
            ->redirect(['profile', 'email'], []);
    }

    #[Route('/connect/google/check', name: 'connect_google_check')]
    public function check(): void
    {
        // This is handled automatically by the guard authenticator
    }
}

✅ 5. Create a Custom OAuth Guard Authenticator

This class handles fetching user info and logging in:

// src/Security/GoogleAuthenticator.php

use KnpU\OAuth2ClientBundle\Security\Authenticator\OAuth2LoginAuthenticator;
use League\OAuth2\Client\Provider\GoogleUser;
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;

class GoogleAuthenticator extends OAuth2LoginAuthenticator
{
    private $clientRegistry;
    private $entityManager;
    private $userRepository;

    public function __construct(ClientRegistry $clientRegistry, EntityManagerInterface $entityManager, UserRepository $userRepository)
    {
        $this->clientRegistry = $clientRegistry;
        $this->entityManager = $entityManager;
        $this->userRepository = $userRepository;
    }

    public function supports(Request $request): ?bool
    {
        return $request->attributes->get('_route') === 'connect_google_check';
    }

    public function authenticate(Request $request): PassportInterface
    {
        $client = $this->clientRegistry->getClient('google');
        $googleUser = $client->fetchUser();

        return new SelfValidatingPassport(
            new UserBadge($googleUser->getEmail(), function ($email) use ($googleUser) {
                $user = $this->userRepository->findOneBy(['email' => $email]);

                if (!$user) {
                    $user = new User();
                    $user->setEmail($email);
                    $user->setGoogleId($googleUser->getId());
                    $user->setName($googleUser->getName());
                    $this->entityManager->persist($user);
                    $this->entityManager->flush();
                }

                return $user;
            })
        );
    }
}

✅ 6. Wire the Authenticator in Security Config

# config/packages/security.yaml

security:
    providers:
        app_user_provider:
            entity:
                class: App\Entity\User
                property: email

    firewalls:
        main:
            custom_authenticators:
                - App\Security\GoogleAuthenticator
            logout:
                path: app_logout
                target: homepage
            remember_me: true

    access_control:
        - { path: ^/connect/google, roles: PUBLIC_ACCESS }

✅ 7. Add Google ID Field to Your User Entity

// src/Entity/User.php

#[ORM\Column(nullable: true)]
private ?string $googleId = null;

Then run:

php bin/console make:migration
php bin/console doctrine:migrations:migrate

✅ 8. Add a Login Button

<a href="{{ path('connect_google_start') }}" class="btn btn-outline-dark">
    Login with Google
</a>

🧪 9. Test the Flow

  1. Visit your Symfony site.
  2. Click "Login with Google".
  3. Authorize via Google.
  4. User is created or retrieved.
  5. You are redirected to your app, logged in.

Would you like me to generate the GoogleAuthenticator.php file in full, scaffold missing parts (like User fields), or help make it reusable for future social logins (like GitHub or Facebook)?