🚀 Integrating Google Login into Symfony using Google Cloud Project
Last updated: June 8, 2025
1. 🤔 Why Use a Google Cloud Project for Google Login?
Your Google Cloud Project is essential because it:
- Enables and manages the Google Identity (OAuth 2.0) API
- Generates OAuth client credentials (Client ID, Secret)
- Defines authorized redirect URIs
- Manages billing, IAM roles, quotas, logs, and more
2. 🛠️ Prerequisites
- PHP 8.4+
- Symfony 7.2+ (or Symfony 5.4+)
- Composer
- A Google Cloud Project with OAuth enabled and a web app client created ✨
Set these in .env.local:
OAUTH_GOOGLE_CLIENT_ID=your-google-client-id
OAUTH_GOOGLE_CLIENT_SECRET=your-google-client-secret
3. 🔌 Integration Steps
3.1 Install Required Libraries
composer require knpuniversity/oauth2-client-bundle league/oauth2-google
3.2 Configure OAuth Client
In config/packages/knpu_oauth2_client.yaml:
knpu_oauth2_client:
clients:
google_main:
type: google
client_id: '%env(OAUTH_GOOGLE_CLIENT_ID)%'
client_secret: '%env(OAUTH_GOOGLE_CLIENT_SECRET)%'
redirect_route: connect_google_check
access_type: offline
redirect_params: []
3.3 Create Controller and Routes
// src/Controller/GoogleController.php
namespace App\Controller;
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
class GoogleController extends AbstractController
{
#[Route('/connect/google', name: 'connect_google_start')]
public function connect(ClientRegistry $clientRegistry)
{
return $clientRegistry
->getClient('google_main')
->redirect(['email', 'profile'], ['prompt' => 'consent', 'access_type' => 'offline']);
}
#[Route('/connect/google/check', name: 'connect_google_check')]
public function check()
{
// Handled by Symfony’s security system
}
}
3.4 Build Custom Authenticator
// src/Security/GoogleAuthenticator.php
namespace App\Security;
use KnpU\OAuth2ClientBundle\Security\Authenticator\OAuth2Authenticator;
// imports...
class GoogleAuthenticator extends OAuth2Authenticator
{
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_main');
$accessToken = $this->fetchAccessToken($client);
return new SelfValidatingPassport(new UserBadge($accessToken->getToken(), function($token) use ($client, $accessToken) {
$googleUser = $client->fetchUserFromToken($accessToken);
$email = $googleUser->getEmail();
$user = $this->em->getRepository(User::class)->findOneBy(['email' => $email]);
if (!$user) {
$user = new User();
$user->setEmail($email);
$this->em->persist($user);
}
$user->setGoogleId($googleUser->getId());
$user->setRefreshToken($accessToken->getRefreshToken());
$this->em->flush();
return $user;
}));
}
public function onAuthenticationSuccess(...): RedirectResponse
{
return new RedirectResponse($this->router->generate('app_homepage'));
}
public function onAuthenticationFailure(...): Response
{
return new Response('Authentication failed', Response::HTTP_FORBIDDEN);
}
}
3.5 Update security.yaml
security:
enable_authenticator_manager: true
firewalls:
main:
custom_authenticators:
- App\Security\GoogleAuthenticator
access_control:
- { path: ^/connect, roles: PUBLIC_ACCESS }
- { path: ^/, roles: ROLE_USER }
4. ✅ Summary
- Installed
knpu/oauth2-client-bundleandleague/oauth2-google - Configured OAuth client in both Google Cloud and Symfony
- Created routes for OAuth flow
- Implemented a custom authenticator
- Updated firewall and access controls
5. 🧭 Next Steps
- Use
access_type: offlineandprompt: consentto obtain refresh tokens - Extend your User entity (add name, avatar, tokens…)
- Protect app routes with
ROLE_USER - Optionally integrate Tokens into other Google APIs like Calendar or Drive
✨ Feedback welcome! Need help with refresh-token logic or multiple social logins? Just ask.
Keywords: Symfony OAuth2 Google, Symfony Google login, OAuth Symfony tutorial