Autenticación de la clave API y acceso

Es necesario emplear el método de autenticación de firma de EAN en todas las solicitudes de API. Junto con la clave API y CID, deberá enviar un hash de firma basado en el secreto compartido, la clave API y un sello temporal UNIX actual. Envíe este hash como el valor del elemento común sig (firma) para todas las solicitudes.

Puede encontrar el secreto compartido de la clave API mediante el inicio de sesión en el Centro de afiliación y la visualización de los Key Details (Detalles de clave) en el menú superior de API.

Durante el desarrollo, puede emplear el generador de sig para crear sus propios valores de sig para solicitudes de prueba en nuestra caja de pruebas, o bien para verificar los valores creados por la implementación.

La autenticación por IP solo se sigue admitiendo para cuentas creadas previamente.

Uso de un secreto compartido para la autenticación y creación de una firma digital en código

Cuando se usa la firma digital, el valor de sig se calcula generando un hash MD5 compuesto por la clave API, el secreto compartido del usuario de la API y un sello temporal UNIX.

El sistema acepta marcas de hora de hasta cinco minutos antes o después de la marca de hora del servidor, con el fin de compensar derivas de reloj razonables.

EAN sincroniza el reloj interno del servidor con Network Time Protocol (NTP). Si también utiliza NTP, no deberían producirse problemas de sincronización del reloj. La mayoría de los sistemas operativos actuales admiten este servicio de sincronización horaria u otros similares; compruebe la documentación de su SO.

La mayor parte de los lenguajes de programación ofrecen alguna versión de la función `md5()`, que debería utilizarse para generar la firma. El ejemplo siguiente ilustra cómo se genera una firma válida con PHP:

$apiKey = 'xxx-YourAPIkey-xxx'; $secret = 'xxYourSecretxx'; $timestamp = gmdate('U'); // 1427233130 (Tue, 24 Mar 2015 21:38:50 +0000) $sig = md5($apiKey . $secret . $timestamp);

La siguiente dirección URL de ejemplo representa una solicitud REST realizada a la Versión 3 del servicio de Hotel mediante una firma digital: una clave API, una marca de hora y un secreto compartido:

http://api.ean.com/ean-services/rs/hotel/v3/avail? cid=[yourCID] &apiKey=[yourAPIKey] &sig=[youSigValue] &minorRev=[current minorRev #] &customerUserAgent=[xxx] &customerIpAddress=[xxx] &locale=en_US &currencyCode=USD &hotelId=201252

NOTA: En la generación de firmas digitales, la marca de hora suele ser una fuente de errores. Asegúrese de:

  • Utilizar la hora GMT, no la hora local.
  • Expresarla en segundos, no en milisegundos. (algunos sistemas expresan la hora en milisegundos de forma predeterminada.)
  • Utilice la marca de hora de la Información del servidor que aparece en el mensaje de error para enviar otra solicitud con el fin de sincronizar su hora con la del servidor si está recibiendo errores de autenticación con las solicitudes de firma (sig). P. EJ.: <ServerInfo serverTime="19:11:13.082-0500" timestamp="1311725473" instance="48" />
Parámetro Descripción
apiKey Identificador de la aplicación del cliente. Es una cadena con una longitud máxima de 255 caracteres y no puede incluir espacios en blanco ni caracteres especiales. Es la clave exclusiva que se le asigna al registrar la aplicación.
sig La firma digital para la solicitud, creada como un hash MD5 de la clave API (apiKey), su secreto compartido y la marca de hora.

Todos los valores de la firma (sig) deben tener una longitud mínima de 32 caracteres en minúscula; por lo tanto, es posible que sea necesario manipular la cadena para añadir un 0 inicial al valor final o cambiar todos los caracteres a minúsculas.

Si recibe errores de autenticación o experimenta otras incidencias cuando genere su propia firma digital, verifique su valor respecto del que aparece en la sección Generador de firmas de EAN.

Elementos de solicitud comunes adicionales

Revise una lista de Elementos de solicitud comunes utilizados en cada llamada de solicitud de datos

Ejemplos de códigos

Puede enviar solicitudes en cualquier lenguaje de programación. A continuación, mostramos ejemplos de código para varios lenguajes habituales (PHP, Python, Java, Ruby, Perl y C#). Cada ejemplo recupera los datos mediante parámetros de consulta con una clave API (apiKey) y la firma digital (sig). Los datos de la respuesta no cambian de un lenguaje a otro.

Para enviar una solicitud sin firma digital y utilizar la autenticación por IP establecida en su cuenta de la API, elimine de las solicitudes el secreto compartido y el proceso de firma.

PHP

Todos los valores de la firma (sig) deben tener un mínimo de 32 caracteres de longitud, por lo tanto, es posible que sea necesario manipular la cadena para añadir un 0 inicial al valor final.

<?php $secret = 'xxYourSecretxx'; $host = 'http://api.ean.com/';  // build path $ver = 'v3/'; $method = 'list/'; $path = "ean-services/rs/hotel/{$ver}{$method}";  // query parameters $apiKey = '[YourAPIkey]'; $cid = '[yourCID]'; $minorRev = '[currentMinorRev]'; $customerUserAgent = 'Mozilla/4.0'; $customerIpAddress = '172.16.82.13'; $locale = 'en_US'; $currencyCode = 'USD'; $hotelId = '201252';  $timestamp = gmdate('U'); $sig = md5($apiKey . $secret . $timestamp);  $query = "?apikey={$apiKey}&cid={$cid}&sig={$sig}&minorRev={$minorRev}" . "&customerUserAgent={$customerUserAgent}&customerIpAddress={$customerIpAddress}" . "&locale={$locale}&currencyCode={$currencyCode}&hotelIdList={$hotelId}";  // initiate curl $ch = curl_init();  curl_setopt($ch, CURLOPT_URL, $host . $path . $query); curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY); curl_setopt($ch, CURLOPT_HTTPHEADER,array('Accept:application/json')); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $data = curl_exec($ch); $headers = curl_getinfo($ch);  // close curl curl_close($ch);  // return XML data if ($headers['http_code'] != '200') {  echo "An error has occurred."; return false; } else {  echo $data;  return($data); } ?>

Python

Si las credenciales son válidas, la llamada devolverá una carga XML en una variable llamada ‘xml.’

Todos los valores de la firma (sig) deben tener un mínimo de 32 caracteres de longitud, por lo tanto, es posible que sea necesario manipular la cadena para añadir un 0 inicial al valor final.

import urllib2 import md5 import time  service = 'http://api.ean.com/ean-services/rs/hotel/' version = 'v3/' method = 'list/' hotelId = '201252' otherElementsStr = 'cid=55505&minorRev=[x]&customerUserAgent=[xxx]&customerIpAddress=[xxx]&locale=en_US&currencyCode=USD'   apiKey = 'YourAPIkey' secret = 'YourSecret'  hash = md5.new() # seconds since GMT Epoch timestamp = str(int(time.time())) # print timestamp sig = md5.new(apiKey + secret + timestamp).hexdigest() url = service + version + method+ '?apiKey=' + apiKey + '&sig=' + sig + otherElementsStr + '&hotelIdList=' + hotelId # print url xml = urllib2.urlopen(url).read()  print xml

Java

El siguiente ejemplo de Java ilustra cómo ejecutar una solicitud de servicio web para obtener datos mediante HTTP GET. Se basa en el paquete HttpComponents de Apache Software Foundation:

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException;  import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient;  public class RestfulCallExample {   public static String service = "http://api.ean.com/ean-services/rs/hotel/";  public static String version = "v3/";  public static String method = "list";  public static String hotelId = "201252";  public static String otherElementsStr = "&cid=55505&minorRev=[x]" + "&customerUserAgent=[xxx]&customerIpAddress=[xxx]&locale=en_US&currencyCode=USD";  public static String apikey = "xxx-YourAPIkey-xxx";  public static String secret = "xxYourSecretxx";   public static void main(String[] args) throws NoSuchAlgorithmException {  MessageDigest md = MessageDigest.getInstance("MD5"); long timeInSeconds = (System.currentTimeMillis() / 1000); String input = apikey + secret + timeInSeconds; md.update(input.getBytes()); String sig = String.format("%032x", new BigInteger(1, md.digest()));  String url = service + version + method+ "?apikey=" + apikey  + "&sig=" + sig + otherElementsStr + "hotelIdList=" + hotelId; System.out.println("URL = " + url); DefaultHttpClient httpclient = new DefaultHttpClient();  // Create an HTTP GET request HttpGet httpget = new HttpGet(url);  // Execute the request httpget.getRequestLine(); HttpResponse response = null; try {  response = httpclient.execute(httpget); } catch (IOException e) {  e.printStackTrace(); return; }   HttpEntity entity = response.getEntity(); // Print the response System.out.println(response.getStatusLine());  if (entity != null) {  try { InputStream inputStream = entity.getContent(); // Process the response BufferedReader bufferedReader = new BufferedReader(  new InputStreamReader(inputStream)); String line; while ((line = bufferedReader.readLine()) != null) {  System.out.println(line); } bufferedReader.close();  } catch (IOException e) { e.printStackTrace();  } } // shut down the connection manager to free up system resources. httpclient.getConnectionManager().shutdown();  } }

Ruby

El siguiente ejemplo de Ruby utiliza Digest::MD5 para generar la firma digital, y Net::HTTP para enviar la solicitud.

Todos los valores de la firma (sig) deben tener un mínimo de 32 caracteres de longitud, por lo tanto, es posible que sea necesario manipular la cadena para añadir un 0 inicial al valor final.

require 'net/http' require 'digest/md5'  # hotelId to send hotelId = '201252'  #additional parameters set in a single string for brevity $otherElemntsStr = '&cid=55505&minorRev=[x]&customerUserAgent=[xxx]&customerIpAddress=[xxx]&locale=en_US&currencyCode=USD'   # API location PRODUCTION_ENDPOINT = 'api.ean.com/ean-services/rs/hotel/' PRODUCTION_PORT = 80  # Your credentials API_KEY = 'YourAPIkey' SHARED_SECRET = 'YourSecret' API_VERSION = 'v3'  current_time = Time.now timestamp = Time.now.to_i.to_s sig = Digest::MD5.hexdigest( API_KEY+SHARED_SECRET+timestamp )  request_url = "/#{API_VERSION}/list}?apiKey=#{API_KEY} & sig=#{sig} & #{otherElementsStr} & hotelIdList=#{hotelId}"  http = Net::HTTP.new( PRODUCTION_ENDPOINT , PRODUCTION_PORT ) http.start do |http| req = Net::HTTP::Get.new(request_url)  resp, data = http.request(req)  print data end

Perl

Todos los valores de la firma (sig) deben tener un mínimo de 32 caracteres de longitud, por lo tanto, es posible que sea necesario manipular la cadena para añadir un 0 inicial al valor final.

# perl  use strict; # use LWP::Simple; use LWP::UserAgent; use Digest::MD5 qw(md5 md5_hex);  my $service = 'http://api.ean.com/ean-services/rs/hotel/'; my $method = 'list/'; my $version= 'v3/'; my $hotelId = '201252'; my $otherElemntsStr = '&cid=[xx]&minorRev=[x]&customerUserAgent=[xxx]&customerIpAddress=[xxx]&locale=en_US&currencyCode=USD';  # key and shared secret obtained from registering application my $apiKey = 'YourAPIkey'; my $secret = 'YourSecret';  my $timestamp = time; #above timestamp needs to be created in PERL !!! Placeholder my $sig = md5_hex($apiKey . $secret . $timestamp);  # print $timestamp,"", $sig, "\n";  my $ua = new LWP::UserAgent; $ua->timeout(120);  my $url=$service . $version . $method. '?apiKey=' . $apiKey . '&sig=' . $sig . $otherElementsStr . '&hotelIdList=' . $hotelId; # print $url, "\n";  my $request = new HTTP::Request('GET', $url); my $response = $ua->request($request); my $xml = $response->content(); print $xml,"\n";

C#

El siguiente ejemplo de C# utiliza HttpWebRequest y HttpWebResponse.

Todos los valores de la firma (sig) deben tener un mínimo de 32 caracteres de longitud, por lo tanto, es posible que sea necesario manipular la cadena para añadir un 0 inicial al valor final.

using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Net; using System.Security.Cryptography;  namespace QuovaRESTSample { class Program { static void Main(string[] args) { string service = "http://api.ean.com/ean-services/rs/hotel/"; string version = "v3/"; string method = "list/"; string hotelId = "201252"; 	string otherElemntsStr = "&cid=[x]&minorRev=[x]&customerUserAgent=[xxx]&customerIpAddress=[xxx]&locale=en_US&currencyCode=USD"; string apiKey = "xxx-YourAPIkey-xxx"; string secret = "xxYourSecretxx"; string sig = MD5GenerateHash(apiKey + secret + (Int32)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds); string fullURL = service + version + method+ "?apiKey=" + apiKey + "&sig=" + sig + otherElementsStr + "&hotelIdList=" + hotelId;  // Create the web request HttpWebRequest request = WebRequest.Create(fullURL) as HttpWebRequest;  // Get response using (HttpWebResponse response = request.GetResponse() as HttpWebResponse) { // Get the response stream StreamReader reader = new StreamReader(response.GetResponseStream());  // Write response to the console Console.WriteLine(reader.ReadToEnd()); }  }  private static string MD5GenerateHash(string strInput) { // Create a new instance of the MD5CryptoServiceProvider object. MD5 md5Hasher = MD5.Create();  // Convert the input string to a byte array and compute the hash. byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(strInput));  // Create a new Stringbuilder to collect the bytes and create a string. StringBuilder sBuilder = new StringBuilder();  // Loop through each byte of the hashed data and format each one as a hexadecimal string. for (int nIndex = 0; nIndex < data.Length; ++nIndex) { sBuilder.Append(data[nIndex].ToString("x2")); }  // Return the hexadecimal string. return sBuilder.ToString(); } } }