In a previous article, I already covered this topic using Google authentication as an example. Today, we’ll do the same with Facebook. (The most complicated part is often obtaining the Facebook API keys.)
One of the benefits of logging in using a Facebook account is that it spares the user from creating yet another password.
Creating the Symfony Project
As usual, we’ll start from scratch and create the project:
symfony new sffacebookNext, let’s add all the required libraries:
composer req twig
composer req --dev symfony/maker-bundle
composer req security
composer req orm
composer req --dev debugAnd specifically those needed for using Facebook for authentication:
composer require knpuniversity/oauth2-client-bundle
composer require league/oauth2-facebookFacebook Configuration
First, obtain your Facebook keys. Log in to the Facebook Developer Portal, go to “My Apps,” and click “Create App.”
Choose “None” as the app type:

Enter your app’s name (e.g., SymfonyAuth) without using reserved words like “Facebook” or “FB.”
Next, add the “Facebook Login” product:

In the left menu, under “Facebook Login,” click “Settings” and configure the valid OAuth redirect URIs (e.g., https://your-domain/connect/facebook/check):

Finally, go to “Settings -> General” and retrieve your app ID and secret. Add them to your .env.local file:
OAUTH_FACEBOOK_CLIENT_ID=app_id
OAUTH_FACEBOOK_CLIENT_SECRET=app_secretCreating the User Entity
Use the MakerBundle to create the User entity:
bin/console make:entityAdd the necessary columns and migrate the database:
bin/console make:migration
bin/console doctrine:migration:migrateConfiguring Authentication
In the config/packages/knpu_oauth2_client.yaml file:
knpu_oauth2_client:
clients:
facebook:
type: facebook
client_id: '%env(OAUTH_FACEBOOK_CLIENT_ID)%'
client_secret: '%env(OAUTH_FACEBOOK_CLIENT_SECRET)%'
redirect_route: connect_facebook_check
graph_api_version: v2.12Creating a Controller
Create a controller to handle login/logout and Facebook authentication:
<?php
namespace App\Controller;
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
class FacebookController extends AbstractController
{
#[Route('/connect/facebook', name: 'connect_facebook')]
public function connectAction(ClientRegistry $clientRegistry): RedirectResponse
{
return $clientRegistry->getClient('facebook')->redirect(['public_profile', 'email'], []);
}
#[Route('/connect/facebook/check', name: 'connect_facebook_check')]
public function connectCheckAction(Request $request)
{
// Handle post-authentication logic
}
}Add a login button to your Twig template (facebook/index.html.twig):
<a href="{{ path('connect_facebook') }}">
<img src="/facebooklogo.png" alt="Log in with Facebook">
</a>Setting Up a GuardAuthenticator
Create a GuardAuthenticator to manage user authentication:
<?php
namespace App\Security;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
use KnpU\OAuth2ClientBundle\Security\Authenticator\OAuth2Authenticator;
use League\OAuth2\Client\Provider\FacebookUser;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
class FacebookAuthenticator extends OAuth2Authenticator
{
public function __construct(
private ClientRegistry $clientRegistry,
private EntityManagerInterface $entityManager,
private RouterInterface $router
) {}
public function authenticate(Request $request): Passport
{
$client = $this->clientRegistry->getClient('facebook');
$accessToken = $this->fetchAccessToken($client);
return new SelfValidatingPassport(
new UserBadge($accessToken->getToken(), function () use ($client, $accessToken) {
$facebookUser = $client->fetchUserFromToken($accessToken);
$email = $facebookUser->getEmail();
$existingUser = $this->entityManager->getRepository(User::class)->findOneBy(['email' => $email]);
if (!$existingUser) {
$existingUser = new User();
$existingUser->setEmail($email);
$this->entityManager->persist($existingUser);
}
$this->entityManager->flush();
return $existingUser;
})
);
}
}Configure security.yaml to use the GuardAuthenticator:
firewalls:
main:
custom_authenticators:
- App\Security\FacebookAuthenticatorConclusion
You can now log in to your site via Facebook. To log out, visit /logout.
The complete code is available on GitHub: https://github.com/gponty/sffacebook
