Skip to content
Binarybox Tutorials

Binarybox Tutorials

Binarybox Tutorials provide tutorials on Web Development and Programming, Learn about Laravel, Symfony, Codeigniter, Javascript other Technologies with our easy step-by-step tutorials

  • Home
  • Programming
    • Laravel
    • CodeIgniter
    • Symfony
    • ReactJS
    • Vue.js
    • Angular
    • Nuxt
  • Anime
  • Tools
  • Contact Us
  • About Us
How To Login with Facebook In Symfony 6
April 29, 2023 PHP / Symfony

How To Login with Facebook In Symfony 6

Avatar photoPosted by Binarybox Tutorials

Contents

  • Prerequisite:
  • Step 1: Install Symfony 6
  • Step 2: Set Database Configuration
  • Step 3: Install Packages
  • Step 4: Configure The Provider
  • Step 5: Create a Dashboard Controller
  • Step 6: Create a User Class
  • Step 7: Create a Migration File
  • Step 8: Create a Login
  • Step 9: Create a Registration
  • Step 10: Create a Facebook Controller
  • Step 11: Run the Application

In this blog, We will show you how to log in with Facebook in Symfony 6. Most of the web apps today allow users to register or log in using their Facebook, Twitter, Google, and other accounts. This is made possible by using OAuth 2.

What is Symfony? Symfony is a PHP framework to develop web applications, APIs, microservices, and web services. Symfony is one of the leading PHP frameworks for creating websites and web applications.

OAuth 2 – is a standard or protocol to implement authorization for any kind of software like desktop applications, mobile applications, and web applications.

Auth0 – is a software product (cloud and on-prem), that implements the OAuth2 protocol. You can use Auth0 to simplify your authentication and authorization requirements.

Prerequisite:

  • Composer
  • Symfony CLI
  • MySQL
  • PHP >= 8.0.2

Step 1: Install Symfony 6

First, select a folder in that you want Symfony to be installed then execute this command on Terminal or CMD to install:

Install via composer:

composer create-project symfony/website-skeleton symfony-6-facebook-login

Install via Symfony CLI:

symfony new symfony-6-facebook-login --full

Step 2: Set Database Configuration

After installing, open the .env file and set the database configuration. We will be using MySQL in this tutorial. Uncomment the DATABASE_URL variable for MySQL and updates its configs. Make sure you commented out the other DATABASE_URL variables.

.env

# In all environments, the following files are loaded if they exist,
# the latter taking precedence over the former:
#
#  * .env                contains default values for the environment variables needed by the app
#  * .env.local          uncommitted file with local overrides
#  * .env.$APP_ENV       committed environment-specific defaults
#  * .env.$APP_ENV.local uncommitted environment-specific overrides
#
# Real environment variables win over .env files.
#
# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES.
#
# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2).
# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration
 
###> symfony/framework-bundle ###
APP_ENV=dev
APP_SECRET=37febf852b869d38be2030babb187e25
###< symfony/framework-bundle ###
 
###> symfony/mailer ###
# MAILER_DSN=smtp://localhost
###< symfony/mailer ###
 
###> doctrine/doctrine-bundle ###
# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml
#
# DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db"
DATABASE_URL="mysql://db_user:db_password@127.0.0.1:3306/db_name?serverVersion=5.7"
# DATABASE_URL="postgresql://db_user:db_password@127.0.0.1:5432/db_name?serverVersion=13&charset=utf8"
###< doctrine/doctrine-bundle ###

After configuring the database, execute this command to create the database:

php bin/console doctrine:database:create

Step 3: Install Packages

We will now install the packages that will do the Facebook login. install these packages – knpuniversity/oauth2-client-bundle and league/oauth2-facebook.

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

Step 4: Configure The Provider

After successfully installing the packages. we will now configure the provider. In this tutorial here is the configuration for Facebook.

config\packages\knpu_oauth2_client.yaml

knpu_oauth2_client:
    clients:
        # the key "facebook_main" can be anything, it
        # will create a service: "knpu.oauth2.client.facebook_main"
        facebook_main:
            # this will be one of the supported types
            type: facebook
            client_id: '%env(OAUTH_FACEBOOK_ID)%'
            client_secret: '%env(OAUTH_FACEBOOK_SECRET)%'
            # the route that you're redirected to after
            # see the controller example below
            redirect_route: connect_facebook_check
            redirect_params: {}
            graph_api_version: v2.12

Then add the OAUTH_FACEBOOK_ID and OAUTH_FACEBOOK_SECRET on the env file. You can get these by registering your app on developers.facebook.com

.env

OAUTH_FACEBOOK_ID=fb_id
OAUTH_FACEBOOK_SECRET=fb_secret

Step 5: Create a Dashboard Controller

After setting up the database, we will then create a controller, this controller will be used by the authenticated user.

To create a controller execute this command:

php bin/console make:controller Dashboard

After executing the command, open this file ‘src\Controller\DashboardController.php’, and add this code:

src\Controller\DashboardController.php

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class DashboardController extends AbstractController
{
    #[Route('/dashboard', name: 'dashboard')]
    public function index(): Response
    {
        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
        return $this->render('dashboard/index.html.twig', [
            'controller_name' => 'DashboardController',
        ]);
    }
}

let’s update the twig file.

templates\dashboard\index.html.twig

{% extends 'base.html.twig' %}

{% block title %}Hello DashboardController!{% endblock %}

{% block body %}
<style>
    .example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; }
    .example-wrapper code { background: #F5F5F5; padding: 2px 6px; }
</style>

<div class="example-wrapper">
    {% if app.user %}
        <div class="mb-3">
            You are logged in as {{ app.user.userIdentifier }}, <a href="{{ path('app_logout') }}">Logout</a>
        </div>
    {% endif %}

    <h1>Hello {{ controller_name }}! ✅</h1>

    This friendly message is coming from:
    <ul>
        <li>Your controller at <code><a href="{{ 'C:/Users/STH ROCKS/Desktop/BLOG SOURCE CODE/SYMFONY 6/symfony-6-login-register-facebook/src/Controller/DashboardController.php'|file_link(0) }}">src/Controller/DashboardController.php</a></code></li>
        <li>Your template at <code><a href="{{ 'C:/Users/STH ROCKS/Desktop/BLOG SOURCE CODE/SYMFONY 6/symfony-6-login-register-facebook/templates/dashboard/index.html.twig'|file_link(0) }}">templates/dashboard/index.html.twig</a></code></li>
    </ul>
    
</div>
{% endblock %}

Step 6: Create a User Class

We will then create a user class, by using the make:user command – this command will create a User class for security and it will automatically update the security.yaml.

Follow these steps:

php bin/console make:user       

 The name of the security user class (e.g. User) [User]:
 >

 Do you want to store user data in the database (via Doctrine)? (yes/no) [yes]:
 >

 Enter a property name that will be the unique "display" name for the user (e.g. email, username, uuid) [email]:
 >

 Will this app need to hash/check user passwords? Choose No if passwords are not needed or will be checked/hashed by some other system (e.g. a single sign-on server).

 Does this app need to hash/check user passwords? (yes/no) [yes]:
 >

 created: src/Entity/User.php
 created: src/Repository/UserRepository.php
 updated: src/Entity/User.php
 updated: config/packages/security.yaml

 
  Success! 
 

 Next Steps:
   - Review your new App\Entity\User class.
   - Use make:entity to add more fields to your User entity and then run make:migration.
   - Create a way to authenticate! See https://symfony.com/doc/current/security.html

Step 7: Create a Migration File

Then we will create a migration file and then migrate it:

Execute this command to create a migration file:

php bin/console make:migration

Then execute this command to run the migration the file:

php bin/console doctrine:migrations:migrate

Step 8: Create a Login

To create a login on Symfony 6, we can use the make:auth command – this command can provide an empty authenticator or a full login form authentication process depending on what you have chosen.

Execute this command and follow the steps below:

php bin/console make:auth       

 What style of authentication do you want? [Empty authenticator]:
  [0] Empty authenticator
  [1] Login form authenticator
 > 1
1

 The class name of the authenticator to create (e.g. AppCustomAuthenticator):
 > AppCustomAuthenticator

 Choose a name for the controller class (e.g. SecurityController) [SecurityController]:
 >

 Do you want to generate a '/logout' URL? (yes/no) [yes]:
 >

 created: src/Security/AppCustomAuthenticator.php
 updated: config/packages/security.yaml
 created: src/Controller/SecurityController.php
 created: templates/security/login.html.twig

           
  Success! 
           

 Next:
 - Customize your new authenticator.
 - Finish the redirect "TODO" in the App\Security\AppCustomAuthenticator::onAuthenticationSuccess() method.
 - Check the user's password in App\Security\AppCustomAuthenticator::checkCredentials().
 - Review & adapt the login template: templates/security/login.html.twig.

After following the steps above, open the file ‘src\Security\AppCustomAuthenticator.php’ and update a part of the code:

src\Security\AppCustomAuthenticator.php

public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
    {
        if ($targetPath = $this->getTargetPath($request->getSession(), $firewallName)) {
            return new RedirectResponse($targetPath);
        }

        // For example:
        return new RedirectResponse($this->urlGenerator->generate('dashboard'));
        // throw new \Exception('TODO: provide a valid redirect inside '.__FILE__);
    }

We will update the SecurityController.php.

src\Controller\SecurityController.php

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;

class SecurityController extends AbstractController
{
    #[Route(path: '/', name: 'app_login')]
    public function login(AuthenticationUtils $authenticationUtils): Response
    {
        if ($this->getUser()) {
            return $this->redirectToRoute('dashboard');
        }

        $error = $authenticationUtils->getLastAuthenticationError();
        $lastUsername = $authenticationUtils->getLastUsername();
        return $this->render('security/login.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
    }

    #[Route(path: '/logout', name: 'app_logout')]
    public function logout(): void
    {
        throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
    }
}

Let’s update the twig file to add the Facebook login.

templates\security\login.html.twig

{% extends 'base.html.twig' %}

{% block title %}Log in!{% endblock %}

{% block body %}
<form method="post">
    {% if error %}
        <div class="alert alert-danger">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
    {% endif %}

    {% if app.user %}
        <div class="mb-3">
            You are logged in as {{ app.user.userIdentifier }}, <a href="{{ path('app_logout') }}">Logout</a>
        </div>
    {% endif %}

    <h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
    <label for="inputEmail">Email</label>
    <input type="email" value="{{ last_username }}" name="email" id="inputEmail" class="form-control" autocomplete="email" required autofocus>
    <label for="inputPassword">Password</label>
    <input type="password" name="password" id="inputPassword" class="form-control" autocomplete="current-password" required>

    <input type="hidden" name="_csrf_token"
           value="{{ csrf_token('authenticate') }}"
    >

    {#
        Uncomment this section and add a remember_me option below your firewall to activate remember me functionality.
        See https://symfony.com/doc/current/security/remember_me.html

        <div class="checkbox mb-3">
            <label>
                <input type="checkbox" name="_remember_me"> Remember me
            </label>
        </div>
    #}

    <button class="btn btn-lg btn-primary" type="submit">
        Sign in
    </button>

    <a href="{{ path('connect_facebook_start') }}">Login Using Facebook</a>
</form>
{% endblock %}

Step 9: Create a Registration

After creating the Login we will then create the Registration. We can use the make:registration command.

Execute this command and follow the steps below:

php bin/console make:registration

 Creating a registration form for App\Entity\User

 Do you want to add a @UniqueEntity validation annotation on your User class to make sure duplicate accounts aren't created? (yes/no) [yes]:
 > 

 Do you want to send an email to verify the user's email address after registration? (yes/no) [yes]:
 > no

 Do you want to automatically authenticate the user after registration? (yes/no) [yes]:
 >

 updated: src/Entity/User.php
 created: src/Form/RegistrationFormType.php
 created: src/Controller/RegistrationController.php
 created: templates/registration/register.html.twig
 
  Success! 
 

 Next:
 Make any changes you need to the form, controller & template.

 Then open your browser, go to "/register" and enjoy your new form!

Step 10: Create a Facebook Controller

Now we will create the controller that will handle the Facebook login.

To create a controller execute this command:

php bin/console make:controller Facebook

After executing the command, open this file ‘src\Controller\FacebookController.php’, and add this code:

<?php

namespace App\Controller;

use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use App\Entity\User;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Security\Http\Authentication\UserAuthenticatorInterface;
use App\Security\AppCustomAuthenticator;

class FacebookController extends AbstractController
{
    #[Route('/connect/facebook', name: 'connect_facebook_start')]
    public function connectAction(ClientRegistry $clientRegistry)
    {
        if ($this->getUser()) {
            return $this->redirectToRoute('dashboard');
        }
        return $clientRegistry
            ->getClient('facebook_main')
            ->redirect([],[
                'public_profile', 'email'
        ]);
    }

   
    #[Route('/connect/facebook/check', name: 'connect_facebook_check')]
    public function connectCheckAction(
        Request $request, 
        ClientRegistry $clientRegistry, 
        UserPasswordHasherInterface $userPasswordHasher,
        EntityManagerInterface $entityManager,
        UserAuthenticatorInterface $userAuthenticator,
        AppCustomAuthenticator $authenticator)
    {
        if ($this->getUser()) {
            return $this->redirectToRoute('dashboard');
        }

        $client = $clientRegistry->getClient('facebook_main');
        
        try {
            
            $facebookUser = $client->fetchUser();

            // check if email exist
            $existingUser  = $entityManager->getRepository(User::class)
                                ->findOneBy(['email' => $facebookUser->getEmail()]);
            if($existingUser){
                return $userAuthenticator->authenticateUser(
                    $existingUser,
                    $authenticator,
                    $request
                );
            }

            $user = new User();
            $user->setPassword(
                $userPasswordHasher->hashPassword(
                    $user,
                    $facebookUser->getId()
                )
            );
            $user->setEmail($facebookUser->getEmail());
            $entityManager->persist($user);
            $entityManager->flush();
            return $userAuthenticator->authenticateUser(
                $user,
                $authenticator,
                $request
            );
        } catch (IdentityProviderException $e) {
            var_dump($e->getMessage()); die;
        }
    }
}

Step 11: Run the Application

After finishing the steps above, you can now run your application by executing the command below:

symfony server:start

After successfully running your app, open these URL’s in your browser:

Login:

https://localhost:8000/

Register:

https://localhost:8000/register

Dashboard(If authenticated):

https://localhost:8000/dashboard
FacebookLoginRegistrationSymfony 6

Post navigation

Previous Post

How To Develop Single Page Application Using Vue.js 3

Next Post

Laravel 10 CRUD Using AJAX with DataTables Tutorial

Tags

AJAX Anime Authentication Breeze CodeIgniter 3 CodeIgniter 4 CRUD DataTable Express Express Js Inertia JWT Laravel Laravel 7 Laravel 8; Laravel 9 Laravel 10 Laravel 11 Laravel 12 Laravel Breeze Laravel Passport Laravel Reverb Login Mailtrap MongoDB Multiple File Upload Must Watch Anime Node Js Page Numbering Payment Gateway PDF PHP QR Code React ReactJS Registration REST API Reverb SPA Stripe Symfony 5 Symfony 6 Symfony 7 Top 10 Vue.js

Newsletter

Recent Posts

  • Top 10 Anime Where the MC Is a Genius or Total Badass
  • Top 10 Anime with Jaw-Dropping Plot Twists
  • Top 10 Magic Anime Where the MC Is Betrayed and Comes Back Overpowered
  • Top 10 Otome Isekai Anime You Must Watch
  • Top 10 Anime Where the Main Character (MC) Went Back in Time

©2020 Binarytuts.com | Terms & Conditions | Privacy Policy

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Cookie settingsACCEPT
Privacy & Cookies Policy

Privacy Overview

This website uses cookies to improve your experience while you navigate through the website. Out of these cookies, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may have an effect on your browsing experience.
Necessary
Always Enabled
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.
SAVE & ACCEPT