Archives de catégorie : Curl

Le module de gestion de la connexion de Salesforce vers Mercedes Cloud (1/3) : Techniques utilisées

Dans les deux premières parties nous avons parlé de l’API Mercedes et on l’a utilisée ‘à la main’ avec CuRL en ligne de commande, puis on a regardé comment utiliser et configurer Salesforce,  puis  programmer des composants visuels avec Salesforce et enfin comment stocker et lire en mode programmation des données dans Salesforce.

Maintenant, on regarde comment programmer ces API Mercedes que l’on a manipulé en CuRL avec les outils de programmation de Salesforce.

1.         La page qui permet de recevoir l’autorisation

Quand on appelé le mécanisme de Mercedes pour obtenir le code d’autorisation, on allait sur une URL Mercedes avec nos données de l’application (dont le client id) , c’était l’étape A ; puis l’utilisateur tapait ses données de connexion pour autoriser l’application (étape B) ; et enfin Mercedes renvoyait sur une page de l’application en passant le code d’autorisation en paramètre (étape C).

L’URL de l’étape C ressemblait à ceci, avec le code obtenu en rouge :

https://localhost/?code=6e9d89c4-a374-4bb9-8c88-673034f87342

Parce qu’on avait dit que la redirect URL de l’application était https://localhost/.

En Salesforce on a besoin de faire une page web qui va savoir lire le paramètre code pour qu’on puisse l’utiliser par la suite.

Le code de la page est simple. Ce sera une page Visual Force, vide pour le moment

<apex:page controller="Mercedes_API_Authorization_Ctrl">
</apex:page>

Avec un controller Mercedes_API_Authorization_Ctrl qui :

  • Stocke le code d’autorisation (en bleu)
  • Lit le paramètre passé quand la page se charge. (en orange).
public class Mercedes_API_Authorization_Ctrl {
    public String authorizationCode { get; set; }
 
public Mercedes_API_Authorization_Ctrl(){
   authorizationCode =
apexpages.currentpage().getparameters().get('code');
}
}

Pour faire plus visible, on peut aussi modifier la page pour qu’elle affiche le paramètre obtenu

<apex:page controller= »Mercedes_API_Authorization_Ctrl »>
  Authorization : {! authorizationCode}
</apex:page>

 

On doit ajouter cette redirect URL à l’application déclarée chez Mercedes :

Essayons d’ouvrir la première URL (etape A), avec la bonne redirect URL (en vert), puis suivons les étapes, on arrive à :

https://api.secure.mercedes-benz.com/oidc10/auth/oauth/v2/authorize?response_type=code&client_id=36f504aa-f141-41ad-93ae-09603cddf507&redirect_uri=https%3A%2F%2Fc.eu16.visual.force.com%2Fapex%2FMercedes_API_Authorization&scope=mb:user:pool:reader%20mb:vehicle:status:general

 

On sait récupérer dans SF le code d’autorisation !

 

2.         Le code pour demander le jeton de session

 

Après avoir reçu le code d’autorisation, quand on travaillait à la main :

  • on devait récupérer les jetons de session
  • on pouvait récupérer les données avec l’API

Maintenant on doit faire la même chose qu’on faisait en Curl, mais en SF, avec le langage APEX.

Avec CuRL, à chaque fois :

  • on créait la requête (la commande tapée)
  • on l’exécutait (appel du serveur Mercedes par le serveur Salesforce), en lançant la commande
  • on traitait le résultat (en le lisant)

On va faire la même chose en programmant.

L’appel CuRL pour l’obtention de la session était

curl -X POST "https://api.secure.mercedes-benz.com/oidc10/auth/oauth/v2/token" \
-H "authorization: Basic ZGY4YTczYmUtYTY4Zi00.....hMWQwLWRjMmM0ZWI4MTU0ZA==" \
-H "content-type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code&code=297ded07-43ea-4fcc-ab73-6b6376d787ca&redirect_uri=https%3A%2F%2Flocalhost.com"

Le Code correspondant en Apex est

  • Préparation de la requête
// creation d’une requête HTTP
HttpRequest req = new HttpRequest();
req.setMethod('POST');

// vers le serveur Mercedes
req.setEndpoint('https://api.secure.mercedes-benz.com/oidc10/auth/oauth/v2/token');

// avec le bon code d’auorisation
req.setHeader('authorization', 'Basic ZGY4YTczYmUtYTY4Zi0.....2NiZTMxYmUxMDM5OjBlYjRmMGE0LTM1YzgtNDc0Ny1hMWQwLWRjMmM0ZWI4MTU0ZA==');
req.setHeader('content-type', 'application/x-www-form-urlencoded');

// avec le message de demande de session
String messageBody =
'grant_type=authorization_code'
+'&code=297ded07-43ea-4fcc-ab73-6b6376d787ca'    +'&redirect_uri=https%3A%2F%2Fc.eu16.visual.force.com%2Fapex%2FMercedes_API_Authorization';
req.setBody(messageBody);
  • Exécution de la requête
//Execute de la requête HTTP
Http http = new Http();
HTTPResponse res = http.send(req);
  • Lecture de la réponse et traitement (juste un affichage)
String jsonResponse = res.getBody();

Map<String, Object> results = (Map<String, Object>)

JSON.deserializeUntyped(jsonResponse);

String access_token = (String)  results.get('access_token');
String token_type   = (String)  results.get('token_type');
Integer expires_in = (Integer) results.get('expires_in');
String refresh_token=  (String)  results.get('refresh_token');
String scope         = (String)  results.get('scope');

System.debug('access_token:' + access_token);
System.debug('token_type:' + token_type);
System.debug('expires_in:' + expires_in);
System.debug('refresh_token:' + refresh_token);
System.debug('scope:' + scope); 

Voici ce qu’on obtient en debug quand on lance le code dans la Console

3.         Le code pour faire un appel API : liste des voitures

De même, pour obtenir la liste des véhicules, on appelait avec CuRL

curl -X GET "https://api.mercedes-benz.com/experimental/connectedvehicle/v1/vehicles"  -H "accept: application/json"  -H "authorization: Bearer f9da01aa-0c07-412b-bb0c-f31a7b413b7b"

On fait les mêmes étapes en Apex :

  • Préparation de la requête (on passe le token obtenu comme avec CuRL)
HttpRequest req = new HttpRequest();
req.setMethod('GET');
req.setHeader('authorization', 'Bearer '+access_token );
req.setHeader('accept', 'application/json');
req.setEndpoint('https://api.mercedes-benz.com/experimental/connectedvehicle/v1/vehicles');
  • Exécution de la requête
Http http = new Http();
HTTPResponse res = http.send(req);
  • Lecture de la réponse et traitement (ici on imprime juste la liste)
String jsonResponse = res.getBody();
System.debug('response:' + jsonResponse);

Voici ce qu’on obtient dans le Debug :

Et voici ! Reste à intégrer ce code manipulé à la main dans une application… Ce sera l’objet des travaux du prochain post !

Connectons-nous au serveur Cloud de Mercedes (2/2) – Utiliser les API avec CuRL

Pour appeler le serveur Mercedes il faut envoyer des commandes REST en https .

J’ai trouvé une explication de l’utilisation de ces commandes sur le site de SCIP : CAR HACKING ANALYSIS OF THE MERCEDES CONNECTED VEHICLE API: www.scip.ch/en/?labs.20180405 .

Nota : Https est un Protocole de transmission permettant à l’utilisateur d’accéder à des pages web par l’intermédiaire d’un navigateur. Rest est une logique d’appel d’API de serveurs.

1.         CURL

CURL est une interface en ligne de commande, destinée à récupérer le contenu d’une ressource accessible par un réseau informatique. La ressource est désignée à l’aide d’une URL et doit être d’un type supporté par le logiciel.

Normalement on ne peut pas utiliser CURL sur Windows mais des personnes ont reprogrammé CURL pour qu’on puisse utiliser CURL sur Windows(https://o7planning.org/fr/11617/installation-de-curl-sous-windows). Donc j’ai téléchargé la version Windows de CURL sur mon PC et j’ai fait un test avec mon Blog et ceci a marché (j’ai bien obtenu le contenu de la page de mon blog dans le fichier mapage.html).

curl » http://wollef.org/fr/mieux-que-pokemon-go-pixelmon-mod/ –output mapage.html

2.         Connexion sécurisée et Redirect URL

a)              Le principe

Avant d’accéder aux données avec l’API il faut montrer qu’on est le propriétaire du compte Mercedes. Ce n’est malheureusement pas aussi simple que de taper un nom d’utilisateur et un mot de passe.

En effet le propriétaire du compte (la personne) doit approuver l’utilisation des données du compte par l’application que l’on a déclarée juste avant.

Le mécanisme est décrit dans l’article de SCIP dont je parle juste avant, et aussi dans la documentation Mercedes  ( https://developer.mercedes-benz.com/content-page/oauth-documentation ).

Pour simplifier cela donne les étapes suivantes :

  • Etape A : L’application qui veut utiliser les données doit envoyer l’utilisateur vers une page Mercedes pour y taper son utilisateur et mot de passe
  • Etape B : L’utilisateur va pouvoir saisir ces informations et dire qu’il approuve l’utilisation des données par l’application
  • Etape C : Le serveur Mercedes renvoie alors l’utilisateur vers l’application en donnant une clé d’accès à celle—ci.

Cette dernière action (le retour vers l’application) se fait avec la ‘redirect url’.

b)              Configuration de la redirect URL

On doit indiquer dans la page de configuration la redirect URL. Pour les premiers tests en CURL, ce sera une url ‘localhost’ (car on n’a pas encore notre serveur avec le jeu en place).

Note : Sur l’impression d’écran, il y a un autre redirect URL, c’est celle de l’application finie (celle intégrée avec salesforce). Nous n’en avons pas besoin pour le moment.

3.         Mise en place de la connexion

La première étape est de connaître les informations qui permettent à l’application d’accéder au serveur Mercedes avec les API.

Ce sont les client id et client secret qui ont été créés quand on a déclaré l’application (ils sont sur dans le texte de ce blog tronqués pour des raison de sécurité, les id réels obtenus et à saisir sont plus longs).

Ensuite, on simule l‘étape A à la main, en tapant l’URL d’authentification dans le navigateur avec le seul client-id:

https://api.secure.mercedes-benz.com/oidc10/auth/oauth/v2/authorize?response_type=code&client_id=36f504aa-f141-41ad-……&redirect_uri=https%3A%2F%2Flocalhost&scope=mb:user:pool:reader%20mb:vehicle:status:general

On arrive sur une page pour se connecter, c’est l’étape B faite par l’utilisateur.

Le serveur Mercedes demande d’approuver la connexion aux données

Ensuite le serveur Mercedes redirige vers une page web (return URL), en donnant un code d‘autorisation unique : 6e9d89c4-a374-4bb9-8c88-673034f87342. C’est l’étape C.

4.         Obtenir le jeton de session

Maintenant on va demander avec l’API (donc en utilisant CURL) d’obtenir le jeton de session qui sera utilisé pour tous les appels suivant à l’API.

Il y a une astuce : c’est que l’appel demande les client Id et client secret dans une forme spéciale qui est l’encodage base 64.

Pour l’obtenir j’ai utilisé une application disponible sur le web : Base 64 Encode https://www.base64encode.net/

Pour encoder, on passe à cette application une chaine de caractère composée du client id et du secret id sépararés par un : (double point).

On obtient la forme encodée des informations suivantes (nota : la partie du milieu est tronquée pour des raisons de sécurité) :

MzZmNTA0YWEtZjE0MS00MWFkLTkz …… QxNjUtNDUwOS04MTdhLTE2YTRkZjViMTM3ZA==

On peut maintenant faire l’appel vers l’API pour initialiser la session en y intégrant le token (incluant donc c lient id et secret id) et le code d’autorisation unique de l’étape B :

curl -X POST « https://api.secure.mercedes-benz.com/oidc10/auth/oauth/v2/token » -H « authorization: Basic MzZmNTA0YWEtZjE0MS00MWFkLTkz……QxNjUtNDUwOS04MTdhLTE2YTRkZjViMTM3ZA== » -H « content-type: application/x-www-form-urlencoded » -d « grant_type=authorization_code&code=6dee706b-9ce9-4f3a-85e8-bd696aae8bef&redirect_uri=https%3A%2F%2Flocalhost »

Hourra ! Le serveur Mercedes nous a renvoyé les jetons de connexion (access token)

5.         Utilisation de la session : appel d’une API : la liste des voitures

Une fois qu’on a un jeton de session on peut s’en servir pour appeler les APIs avec Curl.

On va appeler ici trois API tel que documentées ici : https://developer.mercedes-benz.com/apis/connected_vehicle_experimental_api/ .

a)              Obtenir la liste des voitures

curl -X GET « https://api.mercedes-benz.com/experimental/connectedvehicle/v1/vehicles »  -H « accept: application/json »  -H « authorization: Bearer f9da01aa-0c07-412b-bb0c-f31a7b413b7b »

On peut lire l’Id de la voiture dans la réponse : E09C4378AD45F1A304

Documentation : https://developer.mercedes-benz.com/apis/connected_vehicle_experimental_api/docs#_get_the_vehicleid_from_the_connected_vehicle_api

b)              Obtenir les informations sur la voiture

curl -X GET « https://api.mercedes-benz.com/experimental/connectedvehicle/v1/vehicles/E09C4378AD45F1A304 » -H « accept: application/json » -H « authorization: Bearer f9da01aa-0c07-412b-bb0c-f31a7b413b7b »

Documentation : https://developer.mercedes-benz.com/apis/connected_vehicle_experimental_api/docs#_2_get_additional_information_about_your_car

c)              Verrouiller les portes

curl -X POST « https://api.mercedes-benz.com/experimental/connectedvehicle/v1/vehicles/E09C4378AD45F1A304/doors » -H « Content-Type: application/json » -H « authorization: Bearer f9da01aa-0c07-412b-bb0c-f31a7b413b7b »  -d « { \ »command\ »: \ »LOCK\ »} »

Documentation: https://developer.mercedes-benz.com/apis/connected_vehicle_experimental_api/docs#_4_set_the_lock_state_of_your_car_doors

 

 

Nous voici donc en mesure maintenant d’appeler les API du serveur Cloud de Mercedes pour notre application de jeu ! C’est ce que nous ferons dans les articles prochains !