Bonjour,

Je rencontre un souci pour une connexion FB avec Facebook, j'ai créé 2 methodes, une qui permet d'obtenir "getLoginUrl" dans ma vue Twig et une qui doit me permettre d'obtenir un "AccessToken", mais lorsque que je click sur le lien, je n'ai aucune demande de validation pour la connexion FB ni aucune erreur en retour.

L'appId et l'appSecret sont bien remis, je l'ai ai retiré pour les garder privé :)

Method me permettant de retourner le "getLoginUrl" a ma vue:

/**
     * @Route("/facebook-connect", name="_facebook_connect")
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
     * @throws \Facebook\Exceptions\FacebookSDKException
     */
    public function facebookConnectAction(){
        $fb = new Facebook([
            'app_id' => "", 
            'app_secret' => "",
            'default_graph_version' => 'v2.12',
        ]);

        $oauth= $fb->getOAuth2Client();

        $helper = $fb->getRedirectLoginHelper();

        $permissions = ['email']; 

        $loginUrl = $helper->getLoginUrl($this->redirectToRoute("_facebook_connect_callback"), $permissions);

        return $this->redirectToRoute("_public_login",  compact("loginUrl"));
    }

Method me permettant de récupérer "l'accessToken":

/**
     * @Route("/facebook-connect/callback", name="_facebook_connect_callback")
     * @throws \Facebook\Exceptions\FacebookSDKException
     */
    public function facebookConnectCallbackAction(){
        $fb = new Facebook([
            'app_id' => "",
            'app_secret' => "",
            'default_graph_version' => 'v2.12',
        ]);

        $helper = $fb->getRedirectLoginHelper();

        try {
            $accessToken = $helper->getAccessToken();

        } catch (\Exception $e) {
            // When Graph returns an error
            echo 'Graph returned an error: ' . $e->getMessage();
            exit;
        } catch (\Exception $e) {
            // When validation fails or other local issues
            echo 'Facebook SDK returned an error: ' . $e->getMessage();
            exit;
        }

        if (!isset($accessToken)) {
            if ($helper->getError()) {
                header('HTTP/1.0 401 Unauthorized');
                echo "Error: " . $helper->getError() . "\n";
                echo "Error Code: " . $helper->getErrorCode() . "\n";
                echo "Error Reason: " . $helper->getErrorReason() . "\n";
                echo "Error Description: " . $helper->getErrorDescription() . "\n";
            } else {
                header('HTTP/1.0 400 Bad Request');
                echo 'Bad request';
            }
            exit;
        }

// Logged in
        /*echo '<h3>Access Token</h3>';*/
        var_dump($accessToken->getValue());

// The OAuth 2.0 client handler helps us manage access tokens
        $oAuth2Client = $fb->getOAuth2Client();

// Get the access token metadata from /debug_token
        $tokenMetadata = $oAuth2Client->debugToken($accessToken);
        echo '<h3>Metadata</h3>';
        var_dump($tokenMetadata);

// Validation (these will throw FacebookSDKException's when they fail)
        $tokenMetadata->validateAppId('{app-id}'); // Replace {app-id} with your app id
// If you know the user ID this access token belongs to, you can validate it here
//$tokenMetadata->validateUserId('123');
        $tokenMetadata->validateExpiration();

        if (!$accessToken->isLongLived()) {
            // Exchanges a short-lived access token for a long-lived one
            try {
                $accessToken = $oAuth2Client->getLongLivedAccessToken($accessToken);
            } catch (\Exception $e) {
                echo "<p>Error getting long-lived access token: " . $helper->getMessage() . "</p>\n\n";
                exit;
            }
        }
    }

Vue Twig pour la connexion:

{% extends "front/layout.html.twig" %}
{% block metaDescription %}
    page de connexion
{% endblock %}
{% block title %}
    Connexion
{% endblock %}
{% block content %}
    <div class="content">
        <div class="row">
            <div class="col-sm-4 col-sm-offset-4">
                <div class="page-title">
                    <h1>Connexion</h1>
                    <a href="{{ url('_facebook_connect') }}">se connecter avec Facebook</a>
                </div>
                {% if error %}
                    <div>{{ error.messageKey|trans(error.messageData, 'security') }}</div>
                {% endif %}
                <form method="post" action="{{ path('_login_check') }}">
                    <div class="form-group">
                        <label for="mail">E-mail</label>
                        <input type="email" class="form-control" name="_username" id="mail" value="{{ last_username }}" />
                    </div>
                    <div class="form-group has-error has-feedback">
                        <label for="password">Mot de passe</label>
                        <input type="password" class="form-control" name="_password" id="password" />
                        <span class="fa fa-times form-control-feedback"></span>
                    </div>
                    <button type="submit" class="btn btn-primary pull-right">Connexion</button>
                </form>
            </div>
        </div>
    </div>
{% endblock %}

Merci d'avance pour vos réponses

10 réponses


Bonjour.

mais lorsque que je click sur le lien, je n'ai aucune demande de validation pour la connexion FB ni aucune erreur en retour.

À compter du moment que tu acceptes une première fois l'application, Facebook ne te demanderas plus de l'accepter de nouveau, il n'y a que deux raisons qui peut faire que Facebook te demande à nouveau d'accepter l'application :

  1. Tu as supprimé l'autorisation sur ton compte Facebook
  2. L'application demande ton autorisation pour des données supplémentaires

Je pense donc que tu as déja donné l'autorisation et les autres fois c'est plus rapide car tu as juste la redirection depuis Facebook.
Par contre, au passage, l'API Graph actuelle est la version 2.2 et non la 2.12.

Bonjour, voila j'ai vérifié sur mon compte sur les autorisations des App, aucune ne correspond a celle de mon app et ai modifié la version de l'API Graph en 2.2 mais rien ne change, le comportement reste le meme

Ok.
Il y a quelque chose que je ne comprends pas, ta variable loginUrl qui contient le lien pour la connexion via Facebook, tu l'affiches où ?
Car dans les codes que tu montres, il y en a bien un qui permet de générer le lien et de transmettre la variable, mais aucun n'en montre l'affichage.
Il n'y a qu'un seul fichier twig, mais il ne permet que de se rendre à l'action qui permet de générer le lien.
Pour te connecter via Facebook et l'application, il faudrait cliquer sur le lien qui est contenu dans la variable loginUrl.

oui voila, je mettais trompé dans ma vue Twig, j'ai mis la viarable loginUrl, mais par contre il me dit que la variable n'existe pas alors que je la retourne bien pour cette route.

{% extends "front/layout.html.twig" %}
{% block metaDescription %}
    page de connexion
{% endblock %}
{% block title %}
    Techinfor | Connexion
{% endblock %}
{% block content %}
    <div class="content">
        <div class="row">
            <div class="col-sm-4 col-sm-offset-4">
                <div class="page-title">
                    <h1>Connexion</h1>

                    <a href="{{ loginUrl }}">se connecter avec Facebook</a>
                </div>
                {% if error %}
                    <div>{{ error.messageKey|trans(error.messageData, 'security') }}</div>
                {% endif %}
                <form method="post" action="{{ path('_login_check') }}">
                    <div class="form-group">
                        <label for="mail">E-mail</label>
                        <input type="email" class="form-control" name="_username" id="mail" value="{{ last_username }}" />
                    </div>
                    <div class="form-group has-error has-feedback">
                        <label for="password">Mot de passe</label>
                        <input type="password" class="form-control" name="_password" id="password" />
                        <span class="fa fa-times form-control-feedback"></span>
                    </div>
                    <button type="submit" class="btn btn-primary pull-right">Connexion</button>
                </form>
            </div>
        </div>
    </div>
{% endblock %}

mais par contre il me dit que la variable n'existe pas alors que je la retourne bien pour cette route.

Parce que le second paramètre de redirectToRoute, permet de faire passer des paramètres en GET dans l'url, et non de transférer des variables.

d'accord, le lien fonction et m'envoi bien le client_id mais par contre en retour il me dit que "The parameter redirect_uri is required"

"The parameter redirect_uri is required"

Tu devrais plutôt remplacer :

$loginUrl = $helper->getLoginUrl($this->redirectToRoute("_facebook_connect_callback"), $permissions);

Par :

$loginUrl = $helper->getLoginUrl($this->generateUrl("_facebook_connect_callback"), $permissions);

Par contre, je ne connais pas assez Symfony, pour savoir si la méthode génère une url relative ou absolue, si elle génère une url relative ça va poser problème.

la methode genere une url relative, voila pourquoi j'avais utilisé redirectToRoute

Sauf que la méthode redirectToRoute, comme son nom l'indique sert à faire une redirection, ce qui est totalement hors-contexte étant donné ce qu'attend la méthode getLoginUrl.
Il est possible de générer des url absolues avec la méthode generateUrl :

Generating Absolute URLs
By default, the router will generate relative URLs (e.g. /blog). From a controller, pass UrlGeneratorInterface::ABSOLUTE_URL to the third argument of the generateUrl() method:

use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

$this->generateUrl('blog_show', array('slug' => 'my-blog-post'), UrlGeneratorInterface::ABSOLUTE_URL);
// http://www.example.com/blog/my-blog-post

Il te suffit donc de modifier

$redirectUri = $this->generateUrl("_facebook_connect_callback", [], UrlGeneratorInterface::ABSOLUTE_URL);
$loginUrl = $helper->getLoginUrl($redirectUri, $permissions);

voila apres la modification, il n'arrive toujours pas a recupéré l'accessToken:
"Graph returned an error: Cross-site request forgery validation failed. Required param "state" missing from persistent data."