TP : utilisation de l'API REST de Facebook + Google Maps

De $1

Version de 08:34, 19 Avr 2024

cette version.

Revenir à liste des archives.

Voir la version actuelle

Introduction

Nous allons développer un projet "fil rouge" qui va s'étendre sur plusieurs séances. Il s'agira d'un jeu multi-joueur mettant en oeuvre des "contacts" sur facebook. Dans le TP d'aujourd'hui on va apprendre à utiliser l'API REST de FaceBook et utiliser également Google Maps pour visualiser sur la carte les contacts d'une personne. Par la suite nous utiliserons ces informations pour démarrer une session de jeu avec un des contacts.

Les allergiques à FaceBook où ceux qui ne l'ont jamais utilisé, mettez-vous en binome avec ceux qui l'utilisent ! Ou bien créez un compte facebook bidon, ajoutez  comme amis des collègues de la classe, cela nous sera utile pour faire les TPs. Nous avons choisi FaceBook car il est un des services emblématiques du web 2.0, qu'il utilise des technologies modernes, des modèles de métadonnées issus des travaux sur le web sémantique (le schéma OpenGraph), etc.

Aujourd'hui, résumé en une phrase, nous allons créer en Java une application sur facebook qui récupère la ville de naissance d'un utilisateur et de ses amis, et affiche toutes ces villes sur une carte avec l'api de google maps.

Création de l'application sur Facebook

Pour simplifier les choses, nous vous fournirons des clés d'API et une application/squelette pour développer. La procédure normale est personnelle est plus lourde : il vous faudrait normalement vous inscrire sur la page  des developpeurs,  Il avoir un compte facebook, vérifier votre identité (par téléphone/sms mais bizarrement ça ne marche pas pour la France, et donc la seconde méthode consiste à entrer sa carte bleue, ce qui est un peu difficile à mettre en oeuvre dans le cadre d'un TP !).

Explications sur comment nous avons créé cette application

Pour les curieux, cela se passe ici : Création d'une application facebook.  Suivez ce guide si vous voulez faire votre application à vous, avoir les droits d'administration, la publier plus tard, etc. Pour le moment, vous pouvez regarder la procédure et travailler sur l'application fournie.

Récupérez l'archive de l'application, exécutez-là

Voici l'archive du projet netbeans de l'application. Le projet ne contient qu'une unique page index.jsp et utilise une seule librairie externe (pour l'encodage/décodage du format JSON). Vous pouvez aisément la convertir en projet eclipse si vous êtes un peu dégourdis !

  • TP_1_facebook.rar
  • Désarchivez, ouvrez le projet et déployez-le (vous pouvez faire run, mais cela ne doit pas afficher grand chose, c'est une application Facebook, pas une application web classique),
  • puis ouvrez l'URL "facebook/externe" de la page qui contient l'iframe qui inclut votre application : http://apps.facebook.com/testing_tp/

Normalement on doit vous demander de vous logguer sur votre compte facebook si ce n'est pas déjà fait, puis d'accepter l'application. Si tout s'est bien passé, vous devriez voir l'application :

Snap8.jpg

 

Si vous scrollez vers le bas de la page vous devriez voir une carte google map avec une partie des contacts (les 10 premiers, normalement), affichés. Il n'y en a que dix car Google limite le nombre de requêtes à son API, il faut attendre quelques secondes entre chaque requête ou bien "cacher" les coordonnées des villes dans un fichier ou dans une base de données locale si on veut pouvoir tous les afficher :

Snap9.jpg

Etude du code de l'application

Avant toute choses, il faut comprendre le principe de fonctionnement. Remarquez que pour des raisons de simplicité nous avons tout fait dans une seule page index.jsp, mais pour un "vrai" projet il eut été préférable de séparer traitement et présentation (traitement dans une servlet et présentation dans une JSP par ex). Nous utilisons indifféremment l'API java et l'API javascript de facebook.

Principe de fonctionnement

  • L'application est intégrée dans facebook : dans la page facebook qui contiendra l'application, une iframe HTML incluera l'application qui elle, pourra tourner sur un serveur externe. En phase de développement, nous utiliserons comme adresse externe http://localhost:8080/TP_1_facebook Cette application qui tournera donc sur votre PC sera incluse dans une page du domaine facebook.com
  • Cette application commencera par indiquer l'identité de l'utilisateur de facebook qui exécute l'application (ces informations sont encryptées à l'aide d'une clé qu'on obtient en s'inscrivant sur le site des développeurs, aujourd'hui nous en fournissons une pour tout le monde)
  • Ensuite, on demande à l'API de facebook le détail des actions possibles par l'application pour l'utilisateur qui vient de s'authentifier (accèder à ses données confidentielles, publier sur son mur, accèder aux données de l'utilisateur quand il est offline, les lieux de naissances et anniversaires des amis (permissions dites "étendues"), etc).
  • Si l'application a besoin de certaines actions qui ne sont pas autorisées, elle demande à l'utilisateur s'il est ok pour accorder les permissions correspondantes ("cette application va consulter votre date d'anniversaire, êtres vous d'accord ?")
  • Si l'application obtient tous les accès dont elle a besoin, elle va chercher les informations correspondantes en utilisant l'API facebook. Par exemple, dans notre cas, récupérer la lsite des amis avec le lieu de naissance, leur nom, leur adresse, etc...
  • C'en est fini de la partie "facebook" ! On va ensuite afficher les "lieux de naissance" des amis sur une carte Google Map !

life_cycle.png

Etude du code

Remarquons l'utilisation de librarie JSON pour transformer des objets java en objets javascript et vice-versa. Tout les reponses l'API Facebook javascript sont en JSON, nous utilisons la librairie pour partager ces objets avec le monde Java.

L'application sur facebook a certains parametres (qui sont communiqués lors de sa création depuis la page des développeurs), notamment les clés (Id et clé secrète) ainsi que l'URL facebook de l'application :

public String appId = "148984718491784";

public String appSecret = "484c30ed7c149711c62fcc7c23a0ec70";

public String appUrl = "http://apps.facebook.com/testing_tp/"; 

Suivez maintenant le déroulement du code de la jsp (du haut vers le bas, le code entre <% et %> est exécuté la première fois que la jsp est demandée), ensuite le code du body html est exécuté (le javascript), regardez tout d'abord la partie purement "facebook" avant de voir la partie Google Maps.

L'athentification utilise le protocole OAuth 2.0

Pour vous aider dans votre étude, voici quelques liens très utiles :

On trouve également dans le code cette fonction qui parse la requête envoyée initialement et la décode avec l'algorithme HMAC-SHA256 en utilisant la clé de l'application. Elle renvoie les données utilisateur décodées sous la forme d'un objet JSON (objets sérialisés en javascript).

private static final String ALGORITHM_HMAC_SHA_256 = "HmacSHA256";

public JSONObject parseSignedRequest(String signedRequest, String secret) {
       String[] list = signedRequest.split("\\.");

       if (list.length >= 2) {
           String encodedSig = list[0];
           String payload = list[1];

           try {
               JSONObject data = new JSONObject(new String(fbDecodeBase64(payload)));

               if (!"HMAC-SHA256".equalsIgnoreCase(data.getString("algorithm"))) {
                   logger.println("Unknown algorithm. Expected HMAC-SHA256, signedRequest={}" + signedRequest);
                   return null;
               }

               if (verifySignedRequest(payload, encodedSig, secret)) {
                   //logger.println("Signed Requet verfied! signedRequest={}" + signedRequest);
                   return data;

               } else {
                   //logger.error("Invalid Signed Requet! signedRequest={}", signedRequest);
               }
           } catch (IOException e) {
               //logger.error("Error Decoding Base64, signedRequest="+signedRequest, e);

           } catch (JSONException e) {
               //logger.error("Invalid Json Data, signedRequest="+signedRequest, e);
           }
       }
       return null;
}

public static boolean verifySignedRequest(String payload, String encodedSig, String secret) {
       try {
           byte[] keyBytes = secret.getBytes("UTF-8");

           SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes,ALGORITHM_HMAC_SHA_256);
           Mac mac = Mac.getInstance(ALGORITHM_HMAC_SHA_256);
           mac.init(secretKeySpec);
           byte[] macBytes = mac.doFinal(payload.getBytes());

           String encodedMacBytes = fbEncodeBase64(macBytes);
           return encodedSig.equals(encodedMacBytes);

       } catch (NoSuchAlgorithmException e) {
           //logger.error("Unable to get HmacsSHA256 instance", e);
       } catch (InvalidKeyException e) {
           //logger.error("Invalid Key for HmacsSHA256", e);
       } catch (UnsupportedEncodingException e) {
           //logger.error("Error Getting Bytes Array, secret="+secret, e);
       }
       return false;
   }

   private static String fbEncodeBase64(byte[] bytes) {
       String encodedMacBytes = new BASE64Encoder().encode(bytes);
       encodedMacBytes = encodedMacBytes.replaceAll("\\+", "-");
       encodedMacBytes = encodedMacBytes.replaceAll("/", "_");
       if (encodedMacBytes.endsWith("=")) {
           encodedMacBytes = encodedMacBytes.substring(0,encodedMacBytes.length()-1);
       }
       return encodedMacBytes;
   }

   private static byte[] fbDecodeBase64(String encoded) throws IOException {
       String _encoded = encoded.replaceAll("-", "+");
       _encoded = _encoded.replaceAll("_", "/");
       return new BASE64Decoder().decodeBuffer(_encoded);
   }

Travail à faire

  1. Commentez le code, ajoutez devant les fonctions JS ou Java un commentaire pour vous y retrouver...
  2. Présentez mieux les contacts (dans un tableau ?), voir fonction displayFriends()
  3. Associez à chaque contact un lien HTML qui permet de voir les détails du contact.
  4. Utilisez une base de donnes pour stocker l'infromation de profile et des amis et des response de google maps avec les coordones.
  5. Essayez de voir en lisant la doc Google comment afficher les photos des contacts sur la carte (MarkerImage)
  6. Essayez d'afficher si un contact est online sur facebook ou pas. (Pavel: Ce n'est pas possible, juste l'API de le chat facebook on peut utilise pour ca, mais l'utilisateur peut le deactive)