#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.getBytes("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() возвращает время в секундах , тогда как многие такие функции в других языках / библиотеках возвращают его в миллисекундах .