Возникли проблемы с Преобразованием следующего кода Psuedo в PHP

#java #php #pseudocode

Вопрос:

Удалил старый вопрос и добавил то, что я пробовал до сих пор в PHP, У меня возникла серьезная проблема с преобразованием следующего псевдокода java в PHP, я занимался этим последние 3 часа и не могу заставить его работать. Может кто-нибудь, пожалуйста, помочь. В основном моя главная проблема в том, что я не могу создать правильный authorizationToken, и из-за этого мой вызов API продолжает завершаться неудачно.

Пример запроса API (Псевдокод)

 String  apiKey             = "Your Api Key";
String  secretKey          = "Your Secret Encryption Key";
int     accountId          = "Your Partner Account Id";
int     siteId             = "Your Site Id";
long    unixTime           =  GetEpoch();

String  encodedApiKey      = Base64.getUrlEncoder().withoutPadding().encodeToString(    apiKey.g‌​‌​etBytes("UTF8") );
String  signatureKey       = encodedApiKey   "|"   accountId   "|"   unixTime;

Mac  sha256Hmac            = Mac.getInstance("HmacSHA256");
SecretKeySpec  keySpec     = new SecretKeySpec( secretKey.getBytes(), "HmacSHA256" );
sha256Hmac.init( keySpec );

byte[]  bytesSignatureHash = sha256Hmac.doFinal( signatureKey.getBytes("UTF8") );
String  authorizationToken = encodedApiKey   "."   Base64.getUrlEncoder().withoutPadding().encodeToString( bytesSignatureHash );

String params = "?method=pingamp;epoch=unixTimeamp;locale=en_USamp;customerIPAddress={customer ip address}amp;customerUserAgent={customer user agent}";
String json = "{"echo":"Hello World"}";

URL  url = new URL("https://api.testapi.com/api/v1.7/"   params);
HttpsURLConnection  conn  = (HttpsURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("POST");
conn.setRequestProperty("Authorization",   authorizationToken);
conn.setRequestProperty("x-hp-api-siteid", siteId);
conn.setRequestProperty("content-type",    "application/json; charset=UTF-8");
conn.setDoInput(true);
conn.setDoOutput(true);

OutputStream os = conn.getOutputStream();
os.write( json.getBytes("UTF-8") );
os.close();

InputStream in = new BufferedInputStream( conn.getInputStream() );
String result = org.apache.commons.io.IOUtils.toString(in, "UTF-8");
JSONObject jsonObject = new JSONObject(result);

in.close();
conn.disconnect();
 

Ниже приведен мой php-код

 //  the following is what I've tried so far
$api_key="mykey";
$secret_key="mysecretkey";
$account_id=4345;
$site_id=123;
$unix_time=time(); // Unix Epoch Time


function base64url_encode($data) {
 return rtrim(strtr(base64_encode($data), ' /', '-_'), '=');
} 

$encodedApiKey=base64url_encode($api_key);

$signatureKey  = $encodedApiKey."|".$account_id."|".$unix_time;


echo $authorizationToken =$encodedApiKey.".".base64url_encode(hash_hmac('sha256',$encodedApiKey, $secret_key,true));

$cust_ip=$_SERVER['REMOTE_ADDR'];
$cust_user_agent=$_SERVER['HTTP_USER_AGENT'];

 //  params just updated this var with epoch=unixTime
 $params = "?method=pingamp;epoch=unixTimeamp;locale=en_USamp;customerIPAddress=$cust_ipamp;customerUserAgent=$cust_user_agent";
$url="https://api.testapi.com/api/v1.7/"$params;
//   comment this out 
/* $json_post=json_encode(array(
"method"=>"ping",
"epoch"=>unixTime,
"customerIPAddress"=>$cust_ip,
"customerUserAgent"=>$cust_user_agent,
"method"=>"ping",

));  */

$headers = array( 
'Content-Length: ' . strlen($json_post), 
'Authorization: '.$authorizationToken,
'x-hp-api-siteid: '.$site_id,
'Content-Type: application/json; charset=UTF-8' 
); 
    

//INITIATE CURL WEB SERVICES CALL
$ch2 = curl_init();
curl_setopt($ch2,CURLOPT_URL,$url);
curl_setopt($ch2, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch2,CURLOPT_POST,1);
//curl_setopt($ch2,CURLOPT_POSTFIELDS,$json_post); // update  just commented it out
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
echo $response = curl_exec($ch2);
curl_setopt($ch2, CURLOPT_HEADER, 1);
echo $h = curl_exec($ch2);
curl_close($ch2);
 

Обновление: при наличии полей $json_post и CURLOPT_POST ниже приведен заголовок ответа и ответ json, который я получаю.

Заголовок ответа — Примечание: X-Аутентификация-Статус-Код: 811 (означает пропущенную эпоху)

Длина содержимого: 159 Тип содержимого: приложение/json;кодировка=UTF-8 ETag: 3E96570154DB9F86CEBAEEF2A203E544 Различается: Кодировка принятия,Сервер агента пользователя: ABC.Набор файлов cookie COM: CFID=358841535; Срок действия=Вс, 18 июня-2051 09:40:00 по Гринвичу; Путь=/; Безопасный; Набор файлов cookie HttpOnly: CFTOKEN=c9112fc0099ba33f-996750FC-E74F-91A5-6D464A6C8D3C8759; Срок действия=Вс, 18 июня-2051 09:40:00 по Гринвичу; Путь=/; Безопасный; Набор файлов cookie HttpOnly: LOCALE=en_US; Истекает=Вс, 18 июня-2051 09:40:00 GMT; Путь=/; Безопасный; HttpOnly Set-Cookie: ВАЛЮТА=USD; Путь=/; Безопасный; HttpOnly Set-Cookie: ЯЗЫК=1; Путь=/; Безопасный; HttpOnly Набор файлов cookie: ИСХОДНЫЙ код=Дешевые книги; Истекает срок действия=Ср, 22 декабря 2021 г. 09:40:00 GMT; Путь=/; HttpOnly X-Auth-Статус-Код: 811 Разрешение на управление доступом-Источник: * P3P: CP=»NOI DSP COR LAW NID CUR ADMa НАШЕ дело В ОТНОШЕНИИ ЕДИНСТВЕННОГО ПОЛЬЗОВАТЕЛЯ В СИСТЕМЕ COM NAV STA» X-UA-Совместимо: IE=edge,chrome=1 Разрешение на управление доступом-Заголовки: x-hp-api-идентификатор сайта,тип контента, Управление доступом, Разрешенные учетные данные: истинная Дата: Пт, 25 июня 2021 г. 09:39:59 GMT

Ответ JSON

{«message»:»»,»code»:401,»success»:false,»errors»:[{«message»:»»}],»data»:»»,»instance»:76,»text»:»UNAUTHORIZED»,»token»:»99675141-0ADB-F49B-E3B9EA9A6B5E9CD0″}

Комментарии:

1. Я не эксперт по Java, но похоже, что это, вероятно , настоящая Java, а не псевдокод? Можете ли вы успешно запустить это? И что именно вы подразумеваете под «неудачей»? Какой конкретно ответ вы получаете от API?

2. Разве документация API не содержит словесного объяснения применяемого алгоритма?

3. @CBroe в устном объяснении в значительной степени просто говорится «обратитесь к псевдокоду», что я и сделал.

4. I just noticed that the response header is returning missing epoch time …полезная информация, спасибо. В примере Java данные запроса ?method=pingamp;epoch=unixTimeamp;locale=en_US... — это отправка буквального текста unixTime для параметра «эпоха». Он не отправляет фактическое время, что вы и делаете в PHP. Я думаю, что идея этого состоит в том, чтобы сообщить серверу, какой тип времени вы использовали для вычисления хэша, а не включать текущее время.

5. Кстати, содержит ли документация API код для функции GetEpoch ()? Насколько я могу судить, он не встроенный. И/или в документах обсуждается, какими должны быть единицы измерения времени? Мне приходит в голову, что функция PHP time() возвращает время в секундах , тогда как многие такие функции в других языках / библиотеках возвращают его в миллисекундах .