Autenticação e acesso da chave de API

É necessário aplicar o método de autenticação de assinaturas da EAN para todos as solicitações de API. Além da CID e da chave de API, é necessário enviar uma hash de assinatura baseada em seu segredo compartilhado, sua chave de API e um registro de tempo UNIX atual. Envie a mesma hash e o valor do elemento comum de sig para todas as solicitações.

É possível encontrar o segredo compartilhado da chave de API fazendo o logon na Central de Afiliados e acessando os Dados da chave no menu de API na parte de cima da página.

Durante o desenvolvimento, você pode usar o gerador de sigs para criar os seus valore de sig de forma rápida e fazer testes de solicitações na área restrita ou verificar os valores criados pela sua implementação.

Somente contas previamente estabelecidas ainda receberão suporte para autenticação por IP.

Como usar um segredo compartilhado para autenticação e como criar uma assinatura digital em código

Ao usar a assinatura digital, o valor de sig é calculado gerando uma hash MD5 constituída pela chave de API, o segredo compartilhado do cliente da API e um registro de tempo UNIX.

O sistema aceita registros de tempo de até cinco minutos antes ou depois do registro de tempo do servidor, a fim de acomodar variações aceitáveis entre relógios.

A EAN sincroniza os tempos do servidor interno usando o protocolo NTP. Se você também usar NTP, não devem ocorrer problemas de sincronização de relógio. Os sistemas operacionais mais modernos oferecem suporte a esse serviço de sincronização de tempo ou similares. Consulte a documentação do seu sistema operacional.

A maioria das linguagens de programação fornece alguma versão de uma função `md5()`, a qual deve ser usada para gerar a assinatura. O exemplo seguinte ilustra como gerar uma assinatura válida com PHP (Hypertext Preprocessor):

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

O exemplo seguinte de URL ilustra uma solicitação REST para o serviço de Hotel Versão 3 utilizando uma assinatura digital: chave API, registro de tempo e segredo compartilhado:

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: Em geral, o registro do tempo é fonte de erros na geração de uma assinatura digital. Não esqueça de:

  • Usar o horário GM, não o horário local.
  • Usar segundos, não milissegundos. Certos sistemas dão o tempo em milissegundos por padrão.
  • Utilize o registro de tempo das Informações do Servidor retornado na mensagem de erro para enviar outra solicitação, a fim de sincronizar o seu horário com o do servidor, caso você esteja recebendo erros de autenticação nas solicitações de sig. Exemplo: <ServerInfo serverTime="19:11:13.082-0500" timestamp="1311725473" instance="48" />
Parâmetro Descrição
apiKey Identificador do aplicativo do cliente. Sequência de no máximo 255 caracteres, que talvez não inclua espaços em branco nem caracteres especiais. Esta é a única chave designada a você ao registrar seu aplicativo.
sig A assinatura digital para a solicitação, criada em forma de hash MD5 com apiKey, o seu segredo compartilhado e o registro de tempo.

Todos os valores sig devem ter no mínimo 32 caracteres em letras minúsculas, por isso talvez seja necessária a manipulação da sequência, a fim de acrescentar um 0 na frente do valor final ou alterar todos os caracteres para letras minúsculas.

Se você estiver recebendo erros de autenticação ou outros problemas ao gerar sua própria assinatura digital, verifique o valor no gerador de sig da EAN.

Elementos comuns adicionais de solicitação

Revise uma lista de elementos comuns de solicitação usada em cada chamada de dados

Exemplos de códigos

Você pode enviar solicitações em qualquer linguagem de programação. Os exemplos a seguir são códigos em várias linguagens populares (PHP, Python, Java, Ruby, Perl e C#). Cada exemplo recupera os dados analisando os parâmetros de consulta com uma chave de API (apiKey) e assinatura digital (sig). Os dados na resposta não são alterados de uma linguagem para outra.

Para enviar uma solicitação sem assinatura digital e usar a autenticação IP estabelecida na sua conta de API, remova o segredo compartilhado e o processo de sig das solicitações.

PHP

Todos os valores sig devem ter no mínimo 32 caracteres, por isso talvez seja necessária a manipulação da sequência, a fim de acrescentar um 0 na frente do 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

Se as credenciais forem válidas, a chamada retornará uma carga XML em uma variável denominada ‘xml.’

Todos os valores sig devem ter no mínimo 32 caracteres, por isso talvez seja necessária a manipulação da sequência, a fim de acrescentar um 0 na frente do 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

Os exemplos de Java a seguir ilustram como executar uma solicitação de serviço na web via HTTP GET. Ela conta com o pacote de HttpComponents da 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

Os exemplos de Ruby a seguir usam Digest::MD5 para gerar a assinatura digital, e Net::HTTP para enviar a solicitação.

Todos os valores sig devem ter no mínimo 32 caracteres, por isso talvez seja necessária a manipulação da sequência, a fim de acrescentar um 0 na frente do 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 os valores sig devem ter no mínimo 32 caracteres, por isso talvez seja necessária a manipulação da sequência, a fim de acrescentar um 0 na frente do 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#

Os exemplos de C# a seguir usam HttpWebRequest e HttpWebResponse.

Todos os valores sig devem ter no mínimo 32 caracteres, por isso talvez seja necessária a manipulação da sequência, a fim de acrescentar um 0 na frente do 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(); } } }