Нужно отправить POST-запрос банку для авторизации. Запрос отправляю CURL, но возвращается 404 код. Что делаю не так?
Запрос нужно отправить в таком формате:
POST /secure/token HTTP/1.1
Authorization: Basic строкаАвторизации
Content-Type: application/x-www-form-urlencoded
Request Body:
grant_type=authorization_code&code=<код авторизации>&redirect_uri=<URL возврата>
Отправляю запрос через CURL:
$params=[
'grant_type'=>'authorization_code',
'code'=>$code,
'redirect_uri'=>$uri
];
$headers = [
'POST /secure/token HTTP/1.1',
'Content-Type: application/x-www-form-urlencoded'
];
$curlURL='https://sso.tinkoff.ru';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$curlURL);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, $user . ":" . $pass);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS,http_build_query($params));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_VERBOSE, true);
if(curl_exec($ch)) {
$server_output = json_decode(curl_exec($ch));
}
Что делаю неправильно?
UPD: Разобрался, в чем дело. Дело было в https. Как только получил SSL сертификат — заработало. Спасибо за помощь!
По документации видно, что url
должен быть https://sso.tinkoff.ru/secure/token
, а у вас идет https://sso.tinkoff.ru/
поменяйте урл и все заработает
upd: и оставьте только так
$headers = [
'Content-Type: application/x-www-form-urlencoded'
];
и этот кусок поправьте
if(curl_exec($ch)) {
$server_output = json_decode(curl_exec($ch));
}
на
$curl_res = curl_exec($ch);
if($curl_res) {
$server_output = json_decode($curl_res);
}
а то вы два запроса делаете
libcurl
штука хорошая, но при работе с ней понимать структуру HTTP запросов и ответов всё равно требуется.
Заголовки запроса вам даже из-за включенного CURLOPT_VERBOSE
должны быть видны и там отчётливо виден запрос
POST / HTTP/1.1
Вместо /secure/token
. Почему? Потому что CURLOPT_URL
имеет приоритет над CURLOPT_HTTPHEADER
. Content-Type
же необходимый выставит CURLOPT_POSTFIELDS
самостоятельно.
Как итог - вам не нужен CURLOPT_HTTPHEADER
вообще. Библиотека проставит все заголовки самостоятельно.
Как уже написал в комментариях - каждый вызов curl_exec
осуществляет HTTP запрос. Т.е. ваш код делает два запроса, при том отбрасывает результат первого. Да и результат второго запроса тоже отбрасывает. Потому что json_decode
дальше по коду требует чтобы ему был передан JSON документ. На заголовки HTTP-ответа он отреагирует единственно возможным способом - решит что это не JSON-документ и ответит NULL. А вы никуда ответ не сохранили и вообще не проверили, был ли корректно выполнен запрос через curl_errno
/curl_error
Сторонняя система вполне может считать коды авторизации одноразовыми.
Я очень надеюсь, что вы не системой платежей занимаетесь. Для работы с деньгами у вас очень сильно не хватает ни понимания своего собственного кода ни опыта отладки - это отчётливо видно по комментариям.
// TODO: write to log outcoming request
$ch = curl_init();
/// curl_setopt*
$response = curl_exec($ch);
if (curl_errno($ch)) {
throw new \RuntimeException('Curl error #'. curl_errno($ch) . ': ' .curl_error($ch));
}
$requestInfo = curl_getinfo($ch);
$responseBody = substr($response, $requestInfo['header_size']);
$responseHeaders = substr($response, 0, $requestInfo['header_size']);
// TODO: записать в лог выполненный запрос с полным $requestInfo, $responseBody и $responseHeaders
// TODO: проверить $requestInfo['http_code'] согласно документации API. >=500 явно ошибка, остальные смотреть документацию что должны отвечать
$decodedResponse = json_decode($responseBody);
if (is_null($decodedResponse)) {
throw new \RuntimeException('response is not JSON');
}
// TODO: проверить декодированную структуру на наличие необходимых элементов
Виртуальный выделенный сервер (VDS) становится отличным выбором
Здравствуйте, требуется помощь в написание регулярки для PHP preg_match, нужно вытащить весь текст вместе с тегами (<table>), которые имеют определенный...
На сайте имеется компонент тестирования AriQuizВо время тестирования на вопросы можно отвечать, или пропускать(чтобы ответить позже)
Есть два Инет-провайдеракоторые "отваливаются" с непредсказуемой периодичностью
Как к элементу массива UserName, присвоить данные с input type="text"?