La consommation de webservices REST, ou "API REST" est devenue incontournable. Une authentification avec OAuth 2 est souvent requise, avec ou sans action de l'utilisateur de l'application afin de s'identifier sur le site du fournisseur de l'API.


Grâce aux types httpRequete et httpRéponse ces appels en WLangage se font sans difficulté particulière, à condition de connaître le "principe" d'échange avec le serveur...


Principe :

  • une première prise de contact avec l'API permet d'obtenir au minimum un token, c'est donc juste une première phase d'authentification,
  • les appels suivants sont les appels réels des fonctions de l'API afin d'avoir des données. Ils se font en spécifiant dans les paramètres le token reçu au premier appel.

En pratique :

  • soit c'est l'utilisateur qui va s'authentifier directement via la page fournie par le fournisseur de l'API. Dans ce cas le premier appel au webservice pour l'authentification se fera avec la fonction AuthIdentifie qui recevra les paramètres dans une variable oauth2parametres. Le token nécessaire aux appels suivants est alors reçu dans une variable AuthToken.
  • soit l'authentification complète est faite par programmation. Cela permet par exemple à l'utilisateur de fournir son couple utilisateur/mot de passe dans les champs de l'application, ou un choix de paramétrage, sans avoir à passer par l'interface de connexion du fournisseur de l'API.
    L'application devra alors fournir :
    • pour l'authentification les identifiants ET le couple utilisateur/mot de passe, qui doivent être donnés via une requête POST avec un contenu "grant_type=password".
      La réponse sera généralement un JSON contenant :
      • le token,
      • des informations sur la validité du token,
      • et fréquemment une nouvelle URL qui sera celle à utiliser pour consommer les prochaines fonctions du webservice.
    • pour les appels suivants, on donnera le token d'authentification dans une entête "Authorization = Bearer", et on utilisera la nouvelle URL obtenue à l'authentification.

 

Voici deux solutions pour effectuer cette authentification entièrement par programmation, sans faire appel à la page de connexion du prestataire. Quelque soit le fournisseur, c'est le même principe qui va s'appliquer. Seul le format et la structure de la réponse sera variable. C'est le plus souvent du JSON, et le plus souvent un membre de la structure aura "token" dans son nom ...

 

Solution 1 pour l'authentification (donc obtenir le token) : utilisation d'une unique variable httpRequete ...

 

httpToken_Requete est une httpRequête
httpToken_Réponse est une httpRéponse

sCléClient est une chaîne
sCléSecret est une chaîne
sUtilisateur est une chaîne
sMotPasse est une chaîne

sUtilisateur = "utilisateur@domain.net"
sMotPasse = "Gg334OJn3n..."
sCléClient = "Q65dQf3S2Dd..."
sCléSecret = "ECF89ADFB...."

httpToken_Requete..Méthode = httpPost
httpToken_Requete..URL = "https://adresse-authentification/services/oauth2/token"

// Construction du contenu de la requête POST avec la chaîne standard
// qui concatène toutes les données d'authentification
httpToken_Requete..Contenu = "grant_type=password&username="+sUtilisateur+"&password="+sMotPasse+"&client_id="+sCléClient+"&client_secret="+sCléSecret

httpToken_Réponse = HTTPEnvoie(httpToken_Requete)
// On doit vérifier que httpToken_Réponse..CodeEtat = 200 et traiter les erreurs
jToken est un JSON = httpToken_Réponse..Contenu

 

La variable jToken contient alors le nécessaire pour tous les appels suivants au webservice :

  • jToken.instance_url : l'adresse à laquelle envoyer les appels suivants,
  • jToken.access_token : le token à donner en entête.

Un exemple de réponse :

 

En fonction du prestataire le nom des membres dans le JSON seront différents, mais le principe est toujours le même puisqu'il s'agit d'une implémentation de OAuth2.

 

Solution 2 pour l'authentification (donc pour obtenir le token) : utilisation d'une variable requête, combinée avec les fonctions de création d'un formulaire HTTP ...

 

httpToken_Requete est une httpRequête
httpToken_Réponse est une httpRéponse

sCléClient est une chaîne
sCléSecret est une chaîne
sUtilisateur est une chaîne
sMotPasse est une chaîne

sUtilisateur = "utilisateur@domain.net"
sMotPasse = "Gg334OJn3n..."
sCléClient = "Q65dQf3S2Dd..."
sCléSecret = "ECF89ADFB...."

httpToken_Requete..Méthode = httpPost
httpToken_Requete..URL = "https://adresse-authentification/services/oauth2/token"
httpToken_Requete..ContentType = typeMimeFormulaireSimple

HTTPCréeFormulaire("FORM")
HTTPAjouteParamètre("FORM","grant_type","password")
HTTPAjouteParamètre("FORM","username",sUtilisateur)
HTTPAjouteParamètre("FORM","password",sMotPasse)
HTTPAjouteParamètre("FORM","client_id",sCléClient)
HTTPAjouteParamètre("FORM","client_secret",sCléSecret)
httpToken_Réponse = HTTPEnvoieFormulaire("FORM",httpToken_Requete)



jToken est un JSON = httpToken_Réponse..Contenu

 


Dans le cas générale les deux méthodes sont équivalentes. Cette seconde méthode ajoute quelques lignes de code, mais limite les risques d'erreur de saisie en étant plus lisible que la "concaténation à rallonge". Cette seconde méthode devient par contre incontournable si la requête doit être en "multipart/form-data" (cf typeMimeFormulaireMultiPartie), c'est parfois demandé par un fournisseur d'API REST.

 

Appel des fonctions du webservice REST : que l'authentification soit faite avec la solution 1 ou 2, il suffit d'ajouter le token dans l'entête des appels :

 

httpReqAPI est un httpRequête
httpRéponse est un httpRéponse
J_reponse est un JSON

httpReqAPI..Méthode = httpGet
httpReqAPI..URL = jToken.instance_url+"/services/data/v50.0/mafonction"
httpReqAPI..ContentType = "application/json"
httpReqAPI..Entête["Authorization"] = "Bearer "+jToken.access_token

httpRéponse = HTTPEnvoie(httpReqAPI)
SI httpRéponse..CodeEtat <> 200 ALORS
// Traitement erreur...
SINON
J_reponse = httpRéponse..Contenu
Trace(J_reponse..FormatJSON)
FIN

 

Bon à savoir dans ce domaine :

  • attention au codage ANSI/UNICODE : les fournisseurs d'API attendent des données en ANSI dans le cas général. Le code ci-dessus sera donc immédiatement opérationnel si la configuration du projet a des chaînes ANSI en exécution :

    Si l'application est déployée dans différentes langues qui utilisent des alphabets non latin, donc avec des chaînes en UNICODE, il faudra déclarer les chaînes envoyées à l'API en ANSI : sCléClient est une chaînes ANSI...

  • Si le type JSON est très pratique pour accéder au contenu d'une réponse, il facilite également les appels. Voici un exemple lorsque l'authentification se fait plus simplement en "Authorization = Bearer null". Dans ce cas un simple JSON avec "userName" et "password" est attendu :

 

TestRequete est un restRequête
Test_Réponse est un restRéponse
TestRequete..URL = "https://adresse-authentification/services/authentication/login"
TestRequete..Méthode = httpPost
TestRequete..Entête["Accept"] = "application/json"
TestRequete..Entête["Authorization"] = "Bearer null"
TestRequete..Entête["Content-Type"] = "application/json"

jsAuthentification est un JSON
jsAuthentification.username = "monutilisateur"
jsAuthentification.password = "MkOzdTlkPAwSSE="
TestRequete..Contenu = jsAuthentification..FormatJSON

Test_Réponse = RESTEnvoie(TestRequete)

 

< Retour

Publier un commentaire : 
Votre adresse email ne sera pas publiée