Este tema describe el mecanismo de firma de la API v3 y cómo utilizarlo.
OpenSearch autentica cada solicitud que recibe. Comprueba la identidad del remitente mediante un cifrado simétrico basado en un AccessKey ID y un AccessKey secret.
Alibaba Cloud emite el AccessKey ID y el AccessKey secret para los usuarios. Usted puede solicitarlos y gestionarlos en el sitio web oficial de Alibaba Cloud. El AccessKey ID identifica al usuario.
El AccessKey secret es la clave que se utiliza para cifrar la cadena de firma y comprobarla en el servidor. Debe mantenerse estrictamente confidencial, y solo Alibaba Cloud y el usuario deben conocerlo.
Tipos de aplicación compatibles
Advanced Edition
Standard Edition
Protocolo de comunicación
Solo se admite HTTP.
Métodos de solicitud
Para buscar datos se debe usar: GET
Para insertar datos se debe usar: POST
Cálculo del campo Authorization
Debe agregar el encabezado Authorization a los encabezados de la solicitud HTTP para incluir la información de la firma. Esto indica que la solicitud cuenta con autorización. Los encabezados también deben incluir los parámetros relacionados que se describen en "Encabezado de solicitud", dentro de la sección "Ejemplo de firma" de este tema.
Todos los parámetros incluidos en los encabezados de la solicitud deben usarse en el cálculo de la firma, como Content-Md5, Content-Type, Date y los encabezados específicos de HTTP. Tenga en cuenta que en "Authorization: OPENSEARCH ", después de OPENSEARCH hay un espacio.
"Authorization: OPENSEARCH " + AccessKeyId + ":" + Signature
Signature = base64(hmac-sha1(AccessKeySecret,
VERB + "\n"
+ Content-Md5 + "\n"
+ Content-Type + "\n"
+ Date + "\n"
+ CanonicalizedOpenSearchHeaders
+ CanonicalizedResource))
Calcule el valor de la firma HMAC a partir de la cadena de firma anterior, tal como se define en RFC 2104
El método de firma es HMAC-SHA1, según lo definido en RFC 2104.
La cadena de firma debe estar en formato UTF-8.
Si la cadena de firma contiene caracteres chinos, primero debe codificarse en UTF-8 antes de calcular la firma final con el AccessKeySecret.
Los parámetros de la firma deben seguir el mismo orden que se muestra arriba.
|
Parámetro |
Descripción |
|
AccessKeyId |
Obligatorio. El encabezado Authorization de la solicitud usa este valor de AccessKeyId, que identifica al usuario que accede a la aplicación especificada. |
|
AccessKeySecret |
Obligatorio. La clave que se utiliza para la firma. |
|
VERB |
Obligatorio. El método de la solicitud HTTP, como PUT, GET, POST, HEAD o DELETE. Cada operación utiliza un método distinto. |
|
\n |
El carácter de salto de línea. |
|
Content-MD5 |
Obligatorio cuando el cuerpo de la solicitud tiene contenido. El valor es el hash MD5 del cuerpo de la solicitud. Este encabezado sirve para comprobar la validez del mensaje, es decir, si el contenido coincide con el original enviado. Por ejemplo: . En las solicitudes que no envían un cuerpo, como las consultas, deje este valor vacío. Para obtener más información, consulte RFC2616 Content-MD5. |
|
Content-Type |
|
|
Date |
Obligatorio. La hora de la operación. Debe tener formato ISO con precisión de segundos, como |
|
CanonicalizedOpenSearchHeaders |
Obligatorio. Sirve para distinguir cada solicitud. Es la combinación de los encabezados específicos de HTTP con el prefijo |
|
CanonicalizedResource |
Obligatorio. La ruta de la solicitud, como |
Solicitudes de consulta
|
Parámetro de firma de la solicitud |
Obligatorio |
Parámetro del encabezado de la solicitud |
Obligatorio |
|
AccessKeySecret |
Sí |
Date |
Sí |
|
VERB |
Sí |
X-Opensearch-Nonce |
Sí |
|
Date |
Sí |
Authorization |
Sí |
|
x-opensearch-nonce |
Sí |
||
|
canonicalized_resource |
Sí |
Los valores de los parámetros en los encabezados deben coincidir con los valores correspondientes del método de firma.
Se recomienda agregar Content-Md5, Content-Type, Date, CanonicalizedOpenSearchHeaders y Authorization a los encabezados de la solicitud. Incluir únicamente los parámetros obligatorios puede provocar errores y conviene evitarlo.
Todos los parámetros incluidos en los encabezados de la solicitud deben usarse en el cálculo de la firma.
Solicitudes de inserción
|
Parámetro de firma de la solicitud |
Obligatorio |
Parámetro del encabezado de la solicitud |
Obligatorio |
|
AccessKeySecret |
Sí |
Content-MD5 |
Sí |
|
VERB |
Sí |
Date |
Sí |
|
Content-MD5 |
Sí |
Authorization |
Sí |
|
Date |
Sí |
||
|
canonicalized_resource |
Sí |
Los valores de los parámetros en los encabezados deben coincidir con los valores correspondientes del método de firma.
En principio, Content-Md5, Content-Type, Date, CanonicalizedOpenSearchHeaders y Authorization deben agregarse a los encabezados de la solicitud. Incluir únicamente los parámetros obligatorios puede provocar errores y conviene evitarlo.
Todos los parámetros incluidos en los encabezados de la solicitud deben usarse en el cálculo de la firma.
Construcción de CanonicalizedOpenSearchHeaders
Todos los encabezados específicos de HTTP con el prefijo X-Opensearch- se denominan CanonicalizedOpenSearchHeaders. Los demás encabezados que no son específicos de HTTP no se incluyen en la comprobación.
Complete los valores de todos los encabezados específicos de HTTP con el prefijo
X-Opensearch-, comoX-Opensearch-Nonce : 155108**********. El valor Nonce puede ser la combinación de una marca de tiempo de 10 dígitos y un número aleatorio de 6 dígitos entre 100000 y 999999, por ejemplo,155108**********. Después, elimine todos los encabezados específicos de HTTP cuyos valores estén vacíos.Ordene los encabezados específicos de HTTP que tengan valores en orden lexicográfico ascendente por nombre.
Convierta a minúsculas todos los nombres de los encabezados específicos de HTTP ya ordenados. Por ejemplo, cambie
X-Opensearch-Nonce : 155108**********porx-opensearch-nonce : 155108**********.Quite los espacios a ambos lados del separador entre cada encabezado y su valor. Por ejemplo, tras quitar los espacios, el parámetro
x-opensearch-nonce : 155108**********queda comox-opensearch-nonce:155108**********.Por último, trate cada encabezado y su valor como un elemento, y únalo con
\npara formar el CanonicalizedOpenSearchHeaders final. Tenga en cuenta que el último elemento también debe terminar con\n.
Si los encabezados de la solicitud de consulta no contienen ninguno de estos encabezados específicos de HTTP (es decir, el parámetro está vacío), no se requiere \n. Solo debe eliminar el parámetro de firma CanonicalizedOpenSearchHeaders del método de firma, ya que no se usará en el cálculo.
Cuando agregue encabezados específicos de HTTP a los encabezados de la solicitud, no use la forma convertida a minúsculas. Utilice el formato original.
Construcción de CanonicalizedResource
La cadena de firma debe estar en formato UTF-8. Si contiene caracteres chinos, primero debe codificarse en UTF-8 antes de calcular la firma final con el AccessKeySecret.
Para consultas: CanonicalizedResource = path + ? + query
Para inserciones: CanonicalizedResource = path
Construcción de la ruta
Codifique la ruta en formato URL y luego reemplace %2F por /. Sustituya app_schema_demo en los siguientes ejemplos por el nombre de su aplicación. A continuación se muestran las rutas comunes:
Ruta de la consulta de búsqueda:
/v3/openapi/apps/app_schema_demo/searchRuta de la consulta de sugerencias:
/v3/openapi/suggestions/suggestion_name/actions/searchCadena de solicitud final para consultar la información de una aplicación específica. Reemplace "appid" por el ID de la aplicación que desea consultar. La solicitud debe incluir el parámetro de firma Authorization. No es necesario especificar parámetros de consulta.
/v3/openapi/apps/appidRuta de inserción de datos. tab es el nombre de la tabla específica de la aplicación donde se insertarán los datos, y también debe reemplazarse por el nombre de su tabla.
/v3/openapi/apps/app_schema_demo/tab/actions/bulk
Construcción de la consulta
La consulta se compone de parámetros en forma de pares clave-valor.
Establezca los valores de los parámetros de consulta que desee especificar y elimine aquellos cuyo valor esté vacío. Los parámetros sin valor no se usan en el cálculo de la firma.
Ordene los parámetros en orden lexicográfico ascendente; compare primero el
nombre del parámetroy luego elvalor del parámetro.Codifique en formato URL el
nombre del parámetroy elvalor del parámetrode cada elemento según RFC 3986. Luego, una cada nombre con su valor mediante=.Una los parámetros de consulta con
&y almacene el resultado en la cadena de consulta.-
Por último, concatene el resultado en la cadena CanonicalizedResource con el formato path + ? + query. Con esto se completa la construcción del parámetro CanonicalizedResource para una operación de consulta. Por ejemplo:
/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-
Los parámetros principales y sus valores en la cadena de solicitud anterior son los siguientes:
fetch_fields=name
-
Las cláusulas y los valores de los parámetros en el parámetro query de la cadena anterior son los siguientes. El primer "query" es el parámetro de consulta y el segundo es la cláusula de consulta, seguida de otras cláusulas relacionadas. En este ejemplo, el término de búsqueda es la palabra china para "documento", que aparece como los escapes Unicode ASCII \u6587\u6863. Decodifique estos escapes a los caracteres chinos reales antes de usar el valor. Su codificación URL en UTF-8 es %E6%96%87%E6%A1%A3, tal como se muestra en la cadena de solicitud codificada.
query=query=name:'\u6587\u6863'&&sort=id&&config=format:fulljson
-
Antes de la codificación URL, las cláusulas del parámetro query deben unirse con &&. Para las operaciones de inserción, solo necesita concatenar la ruta en la cadena CanonicalizedResource.
Construcción del campo Authorization
Para conocer el método de construcción, consulte la descripción al inicio de este tema. El campo debe agregarse a los encabezados de la solicitud. Si el AccessKeyId es LTAI**************** y la Signature es 1P7tfE****, el código de ejemplo en Python 3 es aproximadamente el siguiente:
headers['Authorization'] = 'OPENSEARCH ' + 'LTAI****************' + ':' + '1P7tfE****'
Ejemplo de firma
Suponga que los valores de los parámetros son los siguientes:
El valor de Authorization es
OPENSEARCH LTAI****************:1P7tfE****El valor de AccessKeySecret es
yourAccessKeySecretEl método de la solicitud es
GETEl valor de Content-MD5 está vacío porque se trata de una solicitud de consulta
El valor de Content-Type es
application/jsonEl valor de Date es
2019-02-25T10:09:57ZEl valor de CanonicalizedOpenSearchHeaders es
x-opensearch-nonce:15510****1704El valor de CanonicalizedResource es
/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
Encabezado de la solicitud | Fórmula de la cadena de firma | Ejemplo |
‘Content-MD5’: ‘’, ‘Content-Type’: ‘application/json’, ‘Authorization’: ‘OPENSEARCH LTAI:1P7tfE**’,‘X-Opensearch-Nonce’: ‘ | Signature = base64(hmac-sha1(AccessKeySecret,VERB + “\n”+ Content-Md5 + “\n”+ Content-Type + “\n”+ Date + “\n”+ CanonicalizedOpenSearchHeaders+ CanonicalizedResource)) | yourAccessKeySecret,GET\n\napplication/json\n2019-02-25T10:09:57Z\nx-opensearch-nonce: |
Los valores de los parámetros en los encabezados de la solicitud deben coincidir con los valores correspondientes del método de firma.
Calcule la firma (Signature) con el siguiente método
Use hash_hmac y base64_encode para generar el valor cifrado que servirá como Signature.
Código de ejemplo en 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())
Si el valor de AccessKeySecret es yourAccessKeySecret, el valor de la firma construido con el método anterior es 1P7tfE****.
Construcción de la cadena de solicitud
Cadena de solicitud = host + CanonicalizedResource
Debe agregar el encabezado Authorization a los encabezados de la solicitud HTTP para incluir la información de la firma. Esto indica que la solicitud cuenta con autorización. Los encabezados también deben incluir los parámetros relacionados mencionados anteriormente. host es el endpoint de la API de la aplicación.
Cadena final de la solicitud de consulta de búsqueda:
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%3AfulljsonCadena final de la solicitud de consulta de sugerencias:
http://host/v3/openapi/apps/{appName}/suggest/{suggestName}/search?hits=10&query=%E6%A0%87%E9%A2%98Cadena de solicitud final para consultar la información de una aplicación específica. La última parte es el valor "appid". Si suponemos que el valor es 120001234, la cadena tras el reemplazo es la siguiente. Esta solicitud de consulta también debe incluir el parámetro de firma Authorization. No es necesario especificar parámetros de consulta.
http://host/v3/openapi/apps/120001234Cadena final de la solicitud de inserción de datos. Los datos que se van a insertar deben colocarse en el cuerpo de la solicitud.
http://host/v3/openapi/apps/app_schema_demo/tab/actions/bulk
Los SDK oficiales de Java, PHP, Python y C# para la versión v3 ya se publicaron. Los SDK de PHP, Python y C# incluyen el código fuente que implementa el proceso de firma de la API v3, por lo que puede llamar a estos métodos directamente. También puede consultar el código fuente de implementación de la firma en los SDK de PHP, Python y C# para desarrollar SDK en otros lenguajes.
Los SDK que los usuarios desarrollen con base en este tema y en el código fuente son responsabilidad de cada usuario.
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
}
}