Tous les produits
Search
Centre de documentation

OpenSearch:Méthode de signature de l'API OpenSearch V3

Dernière mise à jour :Aug 20, 2026

OpenSearch authentifie chaque requête API par chiffrement symétrique basé sur des paires AccessKey. Chaque paire comprend un AccessKey ID et un AccessKey secret : l'ID identifie l'appelant, tandis que le secret signe la requête. Gardez votre AccessKey secret strictement confidentiel.

OpenSearch propose des SDK pour Java, PHP, Python et C#. Les SDK PHP, Python et C# intègrent nativement la logique de signature. Si un SDK est disponible pour votre langage, utilisez-le et ignorez cette rubrique. Si vous devez implémenter manuellement la signature ou déboguer une erreur de signature, suivez les étapes ci-dessous.

OpenSearch ne maintient ni les SDK développés à partir de cette rubrique, ni le code source des SDK officiels. Il incombe aux utilisateurs d'assurer la maintenance de ces SDK.

Prérequis

Avant de commencer, assurez-vous de disposer des éléments suivants :

  • Un AccessKey ID et un AccessKey secret obtenus depuis la console Alibaba Cloud

  • Une application OpenSearch (Advanced ou Standard)

Fonctionnement

La signature d'une requête comporte six étapes :

  1. Construisez la chaîne CanonicalizedOpenSearchHeaders à partir de tous les en-têtes de requête préfixés par X-Opensearch-*.

  2. Construisez la chaîne CanonicalizedResource à partir du chemin de la requête et des paramètres de requête.

  3. Assemblez la chaîne à signer en combinant la méthode HTTP, les en-têtes et les composants normalisés.

  4. Calculez la signature HMAC-SHA1 de la chaîne à signer en utilisant l'AccessKey secret.

  5. Encodez le résultat HMAC en Base64 pour obtenir la valeur finale de la signature.

  6. Définissez l'en-tête Authorization en y incluant l'AccessKey ID et la signature.

Protocoles et méthodes de requête pris en charge

L'API OpenSearch V3 utilise exclusivement le protocole HTTP.

  • Envoyez des requêtes GET pour rechercher des données.

  • Envoyez des requêtes POST pour envoyer des données.

Étape 1 : Construire CanonicalizedOpenSearchHeaders

La variable CanonicalizedOpenSearchHeaders contient tous les en-têtes de requête préfixés par X-Opensearch- (par exemple, X-Opensearch-Nonce). Si la requête ne comporte aucun en-tête X-Opensearch-*, omettez entièrement ce composant de la chaîne à signer.

Pour construire cette chaîne :

  1. Attribuez des valeurs à tous les en-têtes X-Opensearch-*. Omettez tout en-tête dont la valeur est vide.

  2. Triez les en-têtes restants par ordre alphabétique selon leur nom.

  3. Convertissez chaque nom d'en-tête en minuscules (par exemple, X-Opensearch-Nonce devient x-opensearch-nonce).

  4. Supprimez tous les espaces autour du délimiteur : dans chaque paire en-tête/valeur (par exemple, x-opensearch-nonce : value devient x-opensearch-nonce:value).

  5. Joignez toutes les paires en-tête/valeur avec \n et ajoutez un \n après la dernière paire.

Lors de l'ajout des en-têtes X-Opensearch-* à la requête HTTP réelle, utilisez le format original avec casse mixte ( X-Opensearch-Nonce ), et non la forme en minuscules utilisée pour la signature.

Format de X-Opensearch-Nonce : Un horodatage de 10 chiffres concaténé avec une valeur aléatoire de 6 chiffres comprise entre 100000 et 999999 (par exemple, 155108**********).

Étape 2 : Construire CanonicalizedResource

Le format dépend du type de requête :

  • Requêtes de recherche : path + ? + query

  • Requêtes d'envoi : path uniquement

Construire le chemin

Encodez la chaîne brute du chemin, remplacez %2F par /, et remplacez app_schema_demo par le nom de votre application :

Type de requête Format du chemin
Recherche de données /v3/openapi/apps/<app-name>/search
Recherche par suggestion /v3/openapi/suggestions/<suggestion-name>/actions/search
Recherche par ID d'application /v3/openapi/apps/<app-id>
Envoi de données /v3/openapi/apps/<app-name>/<table-name>/actions/bulk

Construire la chaîne de requête (requêtes de recherche uniquement)

  1. Attribuez des valeurs à chaque paramètre de requête. Omettez les paramètres dont la valeur est vide.

  2. Triez les paramètres par ordre alphabétique, d'abord par clé, puis par valeur.

  3. Encodez chaque clé et valeur en URL conformément à la RFC 3986. Joignez chaque paire avec =.

  4. Concaténez toutes les paires avec &.

  5. Concaténez les clauses de requête au sein du paramètre query en utilisant && avant l'encodage.

Exemple de CanonicalizedResource pour une requête de recherche :

/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27%26%26sort%3Did%26%26config%3Dformat%3Afulljson

Étape 3 : Assembler la chaîne à signer

"Authorization: OPENSEARCH " + AccessKeyId + ":" + Signature

Signature = base64(hmac-sha1(AccessKeySecret,
            VERB + "\n"
            + Content-MD5 + "\n"
            + Content-Type + "\n"
            + Date + "\n"
            + CanonicalizedOpenSearchHeaders
            + CanonicalizedResource))

Tous les paramètres doivent apparaître dans l'ordre indiqué ci-dessus. La chaîne à signer doit être encodée en UTF-8. Si la chaîne contient des caractères chinois, encodez-les en UTF-8 avant de calculer le HMAC.

Incluez un espace après OPENSEARCH dans la valeur de l'en-tête Authorization.

Paramètres

Paramètre Obligatoire Description
AccessKeyId Oui Votre AccessKey ID. Inclus dans l'en-tête Authorization.
AccessKeySecret Oui Votre AccessKey secret. Utilisé pour calculer le HMAC. Ne doit jamais être inclus dans la requête.
VERB Oui Méthode HTTP : GET, POST, PUT, HEAD ou DELETE.
Content-MD5 Conditionnel Valeur MD5 du corps de la requête HTTP (exemple : 4991ef0788236a8f280fed0db928e74e). Obligatoire pour les requêtes d'envoi. Laissez vide pour les requêtes de recherche. Consultez la RFC 2616.
Content-Type — Type MIME du corps de la requête (exemple : application/json).
Date Oui Horodatage de la requête au format ISO 8601 : YYYY-MM-DDThh:mm:ssZ (UTC). Exemple : 2019-02-25T10:09:57Z. OpenSearch rejette les requêtes dont l'horodatage diffère de plus de 15 minutes de l'heure du serveur, en renvoyant une erreur HTTP 403.
CanonicalizedOpenSearchHeaders Conditionnel Tous les en-têtes X-Opensearch-*, en minuscules et triés. Omettez cette ligne de la chaîne à signer si la requête ne contient aucun en-tête X-Opensearch-*.
CanonicalizedResource Oui Le chemin de la requête et la chaîne de requête normalisés.

Étape 4 : Calculer la signature HMAC-SHA1

Utilisez HMAC-SHA1 tel que défini dans la RFC 2104 pour signer la chaîne à signer, en utilisant l'AccessKey secret comme clé.

Étape 5 : Encoder le digest en Base64

Encodez en Base64 les octets bruts du digest HMAC-SHA1 pour produire la valeur finale de la signature.

Étape 6 : Définir l'en-tête Authorization

Authorization: OPENSEARCH <AccessKeyId>:<Signature>

Exemple en Python 3 :

headers['Authorization'] = 'OPENSEARCH ' + 'LTAI****************' + ':' + '1P7tfE****'

En-têtes requis par type de requête

Requêtes de recherche

Paramètre de signature Obligatoire En-tête de requête Obligatoire
AccessKeySecret Oui Date Oui
VERB Oui X-Opensearch-Nonce Oui
Date Oui Authorization Oui
x-opensearch-nonce Oui
canonicalized_resource Oui

Requêtes d'envoi

Paramètre de signature Obligatoire En-tête de requête Obligatoire
AccessKeySecret Oui Content-MD5 Oui
VERB Oui Date Oui
Content-MD5 Oui Authorization Oui
Date Oui
canonicalized_resource Oui

Les valeurs des en-têtes envoyées dans la requête HTTP doivent correspondre exactement aux valeurs utilisées lors du calcul de la signature. Incluez les en-têtes Content-MD5, Content-Type, Date, CanonicalizedOpenSearchHeaders et Authorization dans chaque requête pour éviter les erreurs.

Exemple complet

Cet exemple signe une requête de recherche avec les valeurs suivantes :

Composant Valeur
Méthode de requête GET
AccessKey secret yourAccessKeySecret
Content-MD5 (vide — la requête de recherche n'a pas de corps)
Content-Type application/json
Date 2019-02-25T10:09:57Z
CanonicalizedOpenSearchHeaders x-opensearch-nonce:1551089397451704
CanonicalizedResource /v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27%26%26sort%3Did%26%26config%3Dformat%3Afulljson

Chaîne à signer (utilisez cette valeur intermédiaire pour vérifier votre implémentation) :

GET\n
\n
application/json\n
2019-02-25T10:09:57Z\n
x-opensearch-nonce:1551089397451704\n
/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27%26%26sort%3Did%26%26config%3Dformat%3Afulljson

Calcul de la signature (Python 3) :

import hmac
import base64

signature_string = '\n'.join([
    'GET',
    '',
    'application/json',
    '2019-02-25T10:09:57Z',
    'x-opensearch-nonce:1551089397451704',
    '/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27%26%26sort%3Did%26%26config%3Dformat%3Afulljson'
])

signature_hmac = hmac.new(
    'yourAccessKeySecret'.encode('utf-8'),
    signature_string.encode('utf-8'),
    'sha1'
)
signature = base64.b64encode(signature_hmac.digest())

Signature finale : 1P7tfE****

En-têtes de la requête :

Content-MD5:
Content-Type: application/json
Authorization: OPENSEARCH LTAI****************:1P7tfE****
X-Opensearch-Nonce: 1551089397451704
Date: 2019-02-25T10:09:57Z

Format de la chaîne de requête

Une URL de requête complète suit le format host + CanonicalizedResource. Dans une chaîne de requête, host spécifie l'endpoint de l'API OpenSearch.

Type de requête Exemple d'URL
Recherche de données http://host/v3/openapi/apps/app_schema_demo/search?fetch_fields=name&query=query%3Dname%3A%27%E6%96%87%E6%A1%A3%27%26%26sort%3Did%26%26config%3Dformat%3Afulljson
Recherche par suggestion http://host/v3/openapi/apps/{appName}/suggest/{suggestName}/search?hits=10&query=%E6%A0%87%E9%A2%98
Recherche par ID d'application http://host/v3/openapi/apps/120001234
Envoi de données http://host/v3/openapi/apps/app_schema_demo/tab/actions/bulk

Modèle de schéma d'application

{
  "name": "app_schema_demo",
  "type": "standard",
  "schema": {
    "indexes": {
      "search_fields": {
        "id": {
          "fields": ["id"]
        },
        "name": {
          "fields": ["name"],
          "analyzer": "chn_standard"
        },
        "phone": {
          "fields": ["phone"],
          "analyzer": "fuzzy"
        },
        "int_arr": {
          "fields": ["int_arr"]
        },
        "literal_arr": {
          "fields": ["literal_arr"]
        },
        "cate_id": {
          "fields": ["cate_id"]
        }
      },
      "filter_fields": ["id", "int_arr", "literal_arr", "float_arr", "cate_id"]
    },
    "tables": {
      "tab": {
        "name": "tab",
        "fields": {
          "id": { "name": "id", "type": "INT", "primary_key": true },
          "name": { "name": "name", "type": "TEXT", "primary_key": false },
          "phone": { "name": "phone", "type": "SHORT_TEXT", "primary_key": false },
          "int_arr": { "name": "int_arr", "type": "INT_ARRAY", "primary_key": false },
          "literal_arr": { "name": "literal_arr", "type": "LITERAL_ARRAY", "primary_key": false },
          "float_arr": { "name": "float_arr", "type": "FLOAT_ARRAY", "primary_key": false },
          "cate_id": { "name": "cate_id", "type": "INT", "primary_key": false }
        },
        "primary_table": true
      }
    },
    "route_field": null
  },
  "data_sources": [],
  "first_ranks": {},
  "second_ranks": {},
  "summary": [],
  "fetch_fields": ["id", "name", "phone", "int_arr", "literal_arr", "float_arr", "cate_id"],
  "quota": {
    "qps": 6,
    "doc_size": 0.3
  }
}

Dépannage

Erreur HTTP 403 sur chaque requête

La cause la plus fréquente est un horodatage en dehors de la fenêtre de tolérance de 15 minutes. Assurez-vous que l'en-tête Date utilise l'heure UTC actuelle au format ISO 8601 (YYYY-MM-DDThh:mm:ssZ) et que l'horloge de votre système est synchronisée.

Incompatibilité de signature

Vérifiez les points suivants dans l'ordre :

  1. Vérifiez que la chaîne à signer correspond à la valeur intermédiaire de l'exemple ci-dessus — calculez la chaîne à signer pour votre requête et journalisez-la avant le hachage.

  2. Confirmez que Content-MD5 est vide pour les requêtes GET.

  3. Confirmez que les noms d'en-tête CanonicalizedOpenSearchHeaders sont en minuscules et triés par ordre alphabétique.

  4. Confirmez que les clauses du paramètre query sont concaténées avec && avant l'encodage URL.

  5. Confirmez que la chaîne de signature et l'AccessKey secret sont tous deux encodés en UTF-8 avant le calcul du HMAC.