Aller au contenu principal

Identifier votre application : la carte d'identité d'un appel Conexio

Chaque requête vers l'API Conexio peut porter deux en-têtes HTTP qui disent qui appelle, en quelle version, pourquoi, pour qui et dans quel lot : conexio-agent et traceparent. C'est la carte d'identité de l'appel. Elle ne remplace rien de ce que vous faites déjà : l'authentification reste la Basic Auth avec le header COMPANY_CODE. Elle s'y ajoute.

Recommandée dès maintenant pour toute application qui appelle l'API ; inscrite dans les journaux de la plateforme (voir ce que la plateforme en fait).

Télémétrie, jamais autorisation

Ces en-têtes sont des déclarations de votre application, utiles au support, au diagnostic et aux statistiques. Ils n'ouvrent aucun droit et n'en ferment aucun : l'autorisation reste la licence et la clé d'API. Aucune requête n'est refusée parce qu'un de ces en-têtes manque ou est mal formé. Aucun d'eux n'est un secret : ils peuvent être journalisés tels quels, chez vous comme chez nous.

Pourquoi déclarer votre application​

  • Support. « L'importation de 10 h 42 a échoué » ne permet pas de retrouver un appel parmi des milliers. Un identifiant de lot (traceparent) que vous avez aussi écrit dans votre propre journal, oui : il relie vos lignes de journal aux nôtres.
  • Diagnostic. Sur une même licence, distinguer les appels de votre application de ceux d'un outil de test (Postman ou autre), d'un script ou d'une autre intégration. Une requête sans ces en-têtes est simplement un appel direct : c'est une information, pas une anomalie.
  • Télémétrie. Savoir quelles versions de votre application sont en circulation et quelles fonctionnalités appellent l'API, pour préparer les évolutions sans casser ce qui tourne.

L'en-tête conexio-agent​

Un seul en-tête, qui regroupe les réponses sous forme de clés :

conexio-agent: app=IES, ver="3.2.0.1000", intent=import-data
CléQuestionStatutContenuExemple
appquel logiciel ?recommandéjeton court et stable, propre à l'applicationapp=IES
modulequelle partie du logiciel ?facultatifle composant ou la bibliothèque qui fait l'appel, quand le logiciel en a plusieursmodule=AutotaskAPI
verquelle version ?recommandéla version du logiciel, telle qu'il la connaîtver="3.2.0.1000"
intentpourquoi ?recommandéun jeton par fonctionnalité (pas par requête)intent=import-data
userqui est au volant ?facultatif : seulement si l'application connaît l'utilisateurun identifiantuser=support:simon

Le minimum utile est app + ver + intent, plus l'en-tête traceparent. Rien n'est obligatoire : la plateforme ne refuse jamais une requête à cause de ces en-têtes. Ce que vous y gagnez, c'est d'être retrouvable par le support.

Format​

conexio-agent suit le format dictionnaire des champs structurés HTTP (RFC 8941) :

  • des paires clé=valeur séparées par une virgule et une espace, dans l'ordre app, module, ver, intent, user ;
  • une valeur qui commence par une lettre et ne contient que des lettres, des chiffres et _ - . : / % * s'écrit telle quelle (intent=import-data) ;
  • toute autre valeur s'écrit entre guillemets, avec " et \ échappés par un \ : c'est le cas d'une version, qui commence par un chiffre (ver="3.2.0.1000"), ou d'un identifiant qui contient un @ (user="george@client.ca").

Une clé que le lecteur ne connaît pas est ignorée : de nouvelles clés pourront s'ajouter sans rien casser chez vous ni chez nous.

Règles de valeur​

  • ASCII seulement, pas de retour de ligne, 64 caractères au plus par valeur. Nettoyez la valeur avant de l'envoyer plutôt que de compter sur le serveur : repliez les accents (é → e) et remplacez les espaces par des tirets (« créer facture » → creer-facture).
  • Jamais une valeur vide : si vous ne savez pas, omettez la clé. C'est le cas typique de user pour un service sans utilisateur ou un complément qui ne voit pas la personne connectée. Si vous ne savez même pas app, n'envoyez pas l'en-tête.
  • Le nom de l'en-tête est insensible à la casse, comme tout en-tête HTTP.
  • app : un nom fixe par logiciel, pas par installation ni par client. Nos propres applications utilisent des valeurs réservées : IES, SyncEngine, ClientPortal, PowerBI, WooCommerce, Therefore, AgentService, OnlineERPBackend. Pour la vôtre, choisissez un nom court et stable et gardez-le d'une version à l'autre.
  • intent : un vocabulaire à vous, stable, qui nomme la fonctionnalité en cours (« importer les clients », « synchroniser les factures »), pas la requête ni l'entité. La valeur change quand la fonctionnalité change, pas à chaque appel. Ce n'est pas un texte libre : pas de phrase, pas de description.
  • user : l'identifiant que l'utilisateur vous a donné pour cette application, ou un identifiant interne (support:simon pour une personne du support). Jamais un mot de passe.

Le construire​

const jeton = /^[A-Za-z*][A-Za-z0-9_\-.:%*/]*$/;
const valeur = (v) => (jeton.test(v) ? v : `"${v.replace(/[\\"]/g, "\\$&")}"`);
const conexioAgent = (cles) =>
Object.entries(cles)
.filter(([, v]) => v) // jamais de valeur vide : la clé est omise
.map(([k, v]) => `${k}=${valeur(v)}`)
.join(", ");

conexioAgent({ app: "IES", ver: "3.2.0.1000", intent: "import-data" });
// → 'app=IES, ver="3.2.0.1000", intent=import-data'
Pourquoi un en-tête dédié, un seul, et sans préfixe X-

User-Agent est déjà occupé par les bibliothèques HTTP et un navigateur ou un webview interdit de le modifier depuis fetch : il ne peut pas porter une identité fiable. D'où un en-tête dédié. Un seul plutôt qu'un par question : ajouter une clé plus tard ne touche ni la documentation des en-têtes, ni l'infrastructure, ni les lecteurs existants. Pas de préfixe X- : cette convention est dépréciée depuis la RFC 6648.

traceparent : relier tous les appels d'une même opération​

traceparent est l'en-tête standard du W3C Trace Context. Il reste un en-tête à part, hors de conexio-agent : on l'utilise tel quel plutôt qu'un identifiant maison, parce que les piles .NET le lisent et le propagent nativement, et que n'importe quel outil de traçage (OpenTelemetry, APM) s'y branche sans adaptateur.

traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
│ │ │ │
│ trace-id (32 hex) parent-id (16 hex) flags
version
PartieLongueurCe que c'est
version2 caractèrestoujours 00
trace-id32 caractères hexadécimaux (16 octets)le lot : un identifiant par opération logique — un clic « Importer », une synchronisation, un traitement de nuit. Toutes les requêtes de l'opération portent le même trace-id, y compris chaque page d'une pagination.
parent-id16 caractères hexadécimaux (8 octets)la requête : un identifiant neuf à chaque requête HTTP (souvent appelé span-id).
flags2 caractères01 (sampled) : vous demandez que la trace soit conservée.

Règles : hexadécimal minuscule seulement, longueurs exactes, et jamais un identifiant composé uniquement de zéros (invalide selon le W3C : il serait ignoré).

Le générer​

  • .NET : rien à coder pour le transport. Démarrez une Activity au début de l'opération ; HttpClient ajoute alors traceparent lui-même à chaque requête, avec le trace-id de l'activité et un identifiant neuf par appel (propagation W3C par défaut depuis .NET 5).
  • JavaScript, ou toute autre pile : 16 octets aléatoires pour le trace-id, 8 pour le parent-id, en hexadécimal minuscule, assemblés avec 00- devant et -01 derrière. Prenez une source aléatoire correcte (crypto.getRandomValues, RandomNumberGenerator…), tirez le trace-id une fois par opération et le parent-id à chaque requête.
const hex = (n) => Array.from(crypto.getRandomValues(new Uint8Array(n)), (b) => b.toString(16).padStart(2, "0")).join("");
const traceId = hex(16); // une fois par opération (un lot)
const traceparent = () => `00-${traceId}-${hex(8)}-01`; // à chaque requête

Le journaliser chez vous : c'est ce qui rend le support possible​

Écrivez le trace-id dans votre journal au début de chaque opération (« Début de l'importation — trace 4bf92f3577b34da6a3ce929d0e0e4736 »). Quand un utilisateur vous signale un problème, vous retrouvez la ligne, vous nous transmettez le trace-id, et il désigne exactement les appels du lot. Sans ce pas, le trace-id voyage mais personne ne peut le retrouver.

Exemple complet d'un appel​

Une requête d'importation de clients envoyée par Solution IES, avec l'authentification habituelle et la carte d'identité (clé factice) :

GET /api/Entity/Customer?$top=100 HTTP/1.1
Host: gateway.conexio.dev
Authorization: Basic base64(CODE_LICENCE:api_key_xxxxxxxx)
COMPANY_CODE: PROD_01
conexio-agent: app=IES, ver="3.2.0.1000", intent=import-data
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01

La page suivante de la même importation garde le même trace-id et prend un parent-id neuf ; conexio-agent ne change pas :

GET /api/Entity/Customer?$top=100&$skip=100 HTTP/1.1
Host: gateway.conexio.dev
Authorization: Basic base64(CODE_LICENCE:api_key_xxxxxxxx)
COMPANY_CODE: PROD_01
conexio-agent: app=IES, ver="3.2.0.1000", intent=import-data
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-3c1f0a8e5b7d9a24-01

La même première requête avec curl :

curl 'https://gateway.conexio.dev/api/Entity/Customer?$top=100' \
-u 'CODE_LICENCE:api_key_xxxxxxxx' \
-H 'COMPANY_CODE: PROD_01' \
-H 'conexio-agent: app=IES, ver="3.2.0.1000", intent=import-data' \
-H 'traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01'

Pas de clé user dans cet exemple : Solution IES ne connaît pas l'utilisateur d'Excel et omet donc la clé, plutôt que de l'envoyer vide.

Ce que fait Solution IES (implémentation de référence)​

Le complément Excel Solution IES envoie la carte d'identité ainsi :

Clé ou en-têteCe qu'envoie Solution IES
appIES
verla version du complément
intentla fenêtre en cours, déduite du nom de sa page : import-data, import_gl_transactions, verify_gl_accounts…
useromise — Excel n'expose pas l'utilisateur, la clé n'est jamais envoyée vide
traceparentun trace-id par importation (créé au lancement — bouton « Importer les données » —, libéré à la fin), un parent-id neuf à chaque requête, pages de pagination comprises
  • Les valeurs sont nettoyées avant l'envoi (caractères permis, 64 caractères au plus).
  • Le trace-id est écrit dans le journal du classeur (table IES_LOG, onglet caché IESDATA_LOG) sur la ligne « Début de l'importation … - trace … ». Pour le support : demander le classeur, lire le trace-id, le croiser avec les journaux de la plateforme.

Ce que la plateforme en fait​

La passerelle. Les en-têtes la traversent et arrivent à l'API : rien n'est filtré, rien n'est validé, rien n'est rejeté — une valeur absente ou mal formée n'a aucun effet sur la réponse. La passerelle inscrit conexio-agent dans son journal à chaque appel (ou « aucun » quand l'en-tête manque), sur la même ligne que le trace-id reçu dans traceparent : un trace-id que vous nous transmettez retrouve les appels du lot.

Prochainement. L'API lira aussi conexio-agent et le conservera avec chaque tâche ; les statistiques d'usage par application et par version en découleront.

Les envoyer dès maintenant a un intérêt immédiat : les versions de votre application déjà déployées chez vos clients sont identifiées dès qu'elles passent la passerelle, et votre propre journal porte déjà le trace-id.

Voir aussi​

Cette page vous a-t-elle été utile ?