Todos los productos
Search
Centro de documentos

OpenSearch:Signature method of OpenSearch API V3

Última actualización: Sep 05, 2026

OpenSearch autentica cada solicitud de API mediante cifrado simétrico basado en pares de AccessKey. Cada par consta de un AccessKey ID y un AccessKey secret: el AccessKey ID identifica al solicitante y el AccessKey secret firma la solicitud. Mantenga su AccessKey secret en estricta confidencialidad.

OpenSearch proporciona SDK para Java, PHP, Python y C#. Los SDK de PHP, Python y C# incluyen implementaciones de firma integradas. Si hay un SDK disponible para su lenguaje, úselo y omita este tema. Si necesita implementar la firma manualmente o depurar un error de firma, siga los pasos que se muestran a continuación.

OpenSearch no mantiene los SDK implementados a partir de este tema ni el código fuente de los SDK oficiales. Los usuarios deben mantener estos SDK por su cuenta.

Requisitos previos

Antes de empezar, asegúrese de tener:

  • Un AccessKey ID y un AccessKey secret obtenidos desde la consola de Alibaba Cloud

  • Una aplicación de OpenSearch (Advanced o Standard)

Cómo funciona

La firma de una solicitud incluye seis pasos:

  1. Construya la cadena CanonicalizedOpenSearchHeaders a partir de todos los encabezados de solicitud X-Opensearch-*.

  2. Construya la cadena CanonicalizedResource a partir de la ruta de solicitud y los parámetros de consulta.

  3. Ensamble la cadena para firmar a partir del método HTTP, los encabezados y los componentes canonizados.

  4. Calcule la firma HMAC-SHA1 sobre la cadena para firmar con el AccessKey secret.

  5. Codifique en Base64 el resumen HMAC para obtener el valor final de la firma.

  6. Establezca el encabezado Authorization con el AccessKey ID y la firma.

Protocolos y métodos de solicitud compatibles

OpenSearch API V3 usa solo HTTP.

  • Envíe solicitudes GET para buscar datos.

  • Envíe solicitudes POST para insertar datos.

Paso 1: Construya CanonicalizedOpenSearchHeaders

CanonicalizedOpenSearchHeaders contiene todos los encabezados de solicitud que tienen el prefijo X-Opensearch- (por ejemplo, X-Opensearch-Nonce). Si la solicitud no tiene encabezados X-Opensearch-*, omita este componente por completo de la cadena para firmar.

Para construir la cadena:

  1. Asigne valores a todos los encabezados X-Opensearch-*. Omita cualquier encabezado cuyo valor esté vacío.

  2. Ordene alfabéticamente por nombre los encabezados restantes.

  3. Convierta cada nombre de encabezado a minúsculas (por ejemplo, X-Opensearch-Nonce se convierte en x-opensearch-nonce).

  4. Quite todos los espacios alrededor del delimitador : en cada par encabezado-valor (por ejemplo, x-opensearch-nonce : value se convierte en x-opensearch-nonce:value).

  5. Una todos los pares encabezado-valor con \n y agregue \n después del último par.

Al agregar los encabezados X-Opensearch-* a la solicitud HTTP real, use el formato original con mayúsculas y minúsculas ( X-Opensearch-Nonce ), no la forma en minúsculas que se usa para firmar.

Formato de X-Opensearch-Nonce: una marca de tiempo de 10 dígitos concatenada con un valor aleatorio de 6 dígitos en el rango 100000–999999 (por ejemplo, 155108**********).

Paso 2: Construya CanonicalizedResource

El formato depende del tipo de solicitud:

  • Solicitudes de búsqueda: path + ? + query

  • Solicitudes de inserción: solo path

Construya la ruta

Codifique la cadena de ruta sin procesar, reemplace %2F con / y reemplace app_schema_demo por el nombre de su aplicación:

Tipo de solicitud

Formato de ruta

Búsqueda de datos

/v3/openapi/apps/<app-name>/search

Búsqueda por sugerencia

/v3/openapi/suggestions/<suggestion-name>/actions/search

Búsqueda por ID de aplicación

/v3/openapi/apps/<app-id>

Inserción de datos

/v3/openapi/apps/<app-name>/<table-name>/actions/bulk

Construya la cadena de consulta (solo solicitudes de búsqueda)

  1. Asigne un valor a cada parámetro de consulta. Omita los parámetros con valores vacíos.

  2. Ordene los parámetros alfabéticamente, primero por clave y después por valor.

  3. Codifique cada clave y valor como URL conforme a RFC 3986. Una cada par con =.

  4. Una todos los pares con &.

  5. Concatene las cláusulas de consulta dentro del parámetro query con && antes de codificar.

Ejemplo de CanonicalizedResource para una solicitud de búsqueda:

/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

Paso 3: Ensamble la cadena para firmar

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

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

Todos los parámetros deben aparecer en el orden que se muestra arriba. La cadena para firmar debe estar codificada en UTF-8. Si la cadena contiene caracteres chinos, codifíquelos en UTF-8 antes de calcular el HMAC.

Incluya un espacio después de OPENSEARCH en el valor del encabezado Authorization.

Parámetros

Parámetro

Obligatorio

Descripción

AccessKeyId

Sí

Su AccessKey ID. Se incluye en el encabezado Authorization.

AccessKeySecret

Sí

Su AccessKey secret. Se usa para calcular el HMAC. Nunca se incluye en la solicitud.

VERB

Sí

Método HTTP: GET, POST, PUT, HEAD o DELETE.

Content-MD5

Condicional

El valor MD5 del cuerpo de la solicitud HTTP (ejemplo: 4991ef0788236a8f280fed0db928e74e). Es obligatorio para las solicitudes de inserción. Déjelo en blanco para las solicitudes de búsqueda. Consulte RFC 2616.

Content-Type

—

Tipo de medio del cuerpo de la solicitud (ejemplo: application/json).

Date

Sí

Marca de tiempo de la solicitud en formato ISO 8601: YYYY-MM-DDThh:mm:ssZ (UTC). Ejemplo: 2019-02-25T10:09:57Z. OpenSearch rechaza las solicitudes cuya marca de tiempo difiere de la hora del servidor en más de 15 minutos y devuelve HTTP 403.

CanonicalizedOpenSearchHeaders

Condicional

Todos los encabezados X-Opensearch-*, en minúsculas y ordenados. Omita esta línea de la cadena para firmar si la solicitud no tiene encabezados X-Opensearch-*.

CanonicalizedResource

Sí

La ruta de solicitud y la cadena de consulta canonizadas.

Paso 4: Calcule la firma HMAC-SHA1

Use HMAC-SHA1 tal como se define en RFC 2104 para calcular la firma sobre la cadena para firmar, con el AccessKey secret como clave.

Paso 5: Codifique en Base64 el resumen

Codifique en Base64 los bytes del resumen HMAC-SHA1 sin procesar para generar el valor final de la firma.

Paso 6: Establezca el encabezado Authorization

Authorization: OPENSEARCH <AccessKeyId>:<Signature>

Ejemplo en Python 3:

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

Encabezados obligatorios por tipo de solicitud

Solicitudes de búsqueda

Parámetro de firma

Obligatorio

Encabezado de solicitud

Obligatorio

AccessKeySecret

Sí

Date

Sí

VERB

Sí

X-Opensearch-Nonce

Sí

Date

Sí

Authorization

Sí

x-opensearch-nonce

Sí

canonicalized_resource

Sí

Solicitudes de inserción

Parámetro de firma

Obligatorio

Encabezado de solicitud

Obligatorio

AccessKeySecret

Sí

Content-MD5

Sí

VERB

Sí

Date

Sí

Content-MD5

Sí

Authorization

Sí

Date

Sí

canonicalized_resource

Sí

Los valores de encabezado enviados en la solicitud HTTP deben coincidir exactamente con los valores usados durante el cálculo de la firma. Incluya los encabezados Content-MD5, Content-Type, Date, CanonicalizedOpenSearchHeaders y Authorization en todas las solicitudes para evitar errores.

Ejemplo completo

Este ejemplo firma una solicitud de búsqueda con los valores que se muestran a continuación:

Componente

Valor

Método de solicitud

GET

AccessKey secret

yourAccessKeySecret

Content-MD5

(en blanco; la solicitud de búsqueda no tiene cuerpo)

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

Cadena para firmar (use este valor intermedio para que compruebe su implementación):

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

Cálculo de la firma (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())

Firma final: 1P7tfE****

Encabezados de solicitud:

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

Formato de la cadena de solicitud

Una URL de solicitud completa tiene el formato host + CanonicalizedResource. En una cadena de solicitud, host especifica el endpoint de la API de OpenSearch.

Tipo de solicitud

URL de ejemplo

Búsqueda de datos

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

Búsqueda por sugerencia

http://host/v3/openapi/apps/{appName}/suggest/{suggestName}/search?hits=10&query=%E6%A0%87%E9%A2%98

Búsqueda por ID de aplicación

http://host/v3/openapi/apps/120001234

Inserción de datos

http://host/v3/openapi/apps/app_schema_demo/tab/actions/bulk

Plantilla de esquema de aplicación

{
  "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
  }
}

Solución de problemas

Error HTTP 403 en todas las solicitudes

La causa más común es una marca de tiempo fuera de la ventana de tolerancia de 15 minutos. Asegúrese de que el encabezado Date use la hora UTC actual en formato ISO 8601 (YYYY-MM-DDThh:mm:ssZ) y de que el reloj de su sistema esté sincronizado.

La firma no coincide

Compruebe los puntos que se indican a continuación, en orden:

  1. Compruebe que la cadena para firmar coincide con el valor intermedio del ejemplo anterior: calcule la cadena para firmar de su solicitud y regístrela antes de calcular el hash.

  2. Confirme que Content-MD5 está en blanco para las solicitudes GET.

  3. Confirme que los nombres de encabezado de CanonicalizedOpenSearchHeaders están en minúsculas y ordenados alfabéticamente.

  4. Confirme que las cláusulas del parámetro query se concatenan con && antes de codificar la URL.

  5. Confirme que la cadena para firmar y el AccessKey secret están codificados en UTF-8 antes de calcular el HMAC.