Я пытаюсь войти в Betfair через API Betfair, используя curl. Я уже преуспел в этом через версию curl для командной строки из скрипта bash, но теперь я хочу сделать это из своего кода C ++ напрямую с помощью libcurl. К сожалению, libcurl не поддерживается betfair, поэтому прямой документации нет, но если сгибание командной строки работает, то все должно быть выполнимо.
Мой libcurl сразу не работает во время попытки входа в систему (который должен получить «токен сеанса» в качестве ответа). Я говорю curl о своем сертификате и ключе со строками:
curl_easy_setopt(curl, CURLOPT_SSLCERT,"client-2048.crt");
curl_easy_setopt(curl, CURLOPT_SSLKEY,"client-2048.key");
Позже я звоню curl_easy_perform(curl);
Я получаю ответ:
{"loginStatus":"CERT_AUTH_REQUIRED"}
В соответствии с Betfair документация это означает: «Требуется сертификат или сертификат присутствует, но не может аутентифицироваться с ним»
Поэтому я предполагаю, что аутентификация SSL как-то не удалась. В качестве эксперимента я попытался преднамеренно поместить сертификаты мусора и имена файлов ключей (например, «client-2048_XXX.crt»), но не увидел различий в ответе от Betfair или какой-либо из диагностики скручивания (настроенной через curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, my_trace);
а также curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
). Поэтому я не могу точно знать, что libcurl правильно обработал мои файлы сертификатов и ключей. На самом деле я даже подозреваю, что, возможно, он вообще не обрабатывает их — возможно, я упускаю какой-то другой параметр в соответствии с CURLOPT_PLEASE_USE_SSL_AUTHENTICATION, который приводит к игнорированию файлов?
РЕДАКТИРОВАТЬ: Итак, для записи, полная последовательность выглядит следующим образом (часть текста скрыта):
curl_easy_setopt(curl, CURLOPT_URL, "https://identitysso.betfair.com/api/certlogin");
curl_easy_setopt(curl, CURLOPT_SSLCERT,"client-2048.crt");
curl_easy_setopt(curl, CURLOPT_SSLKEY,"client-2048.key");
curl_easy_setopt(curl, CURLOPT_POST, 1);
struct curl_slist *chunk = NULL;
chunk = curl_slist_append(chunk, "X-Application: _HIDDEN_");
chunk = curl_slist_append(chunk,"Content-Type: application/x-www-form-urlencoded");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS,"username=_HIDDEN_&password=_HIDDEN_");
curl_easy_perform(curl);
РЕДАКТИРОВАТЬ: Я подумал, что, возможно, я как-то скомпилировал свой libcurl без SSL. Чтобы проверить это, я вызвал curl_version_info, который, помимо прочего, дает вам:
char *ssl_version; /* human readable string */
Распечатка этого дала строку «WinSSL», которая, как я предполагаю, означает, что SSL включен.
РЕДАКТИРОВАТЬ: К вашему сведению, у меня есть четыре файла «client-2048», .crt, .pem, .key и .csr. Все они находятся в одном каталоге с моим exe-файлом. Я также распечатываю текущий рабочий каталог (как сообщает _getcwd ()) во время выполнения, просто дважды проверь, что мой exe работает из правильного места.
РЕДАКТИРОВАТЬ: Вот мой рабочий login.sh (прошу прощения за то, что он не элегантен, я взламывал код и вставлял код и почти не знал, что я делаю). getlog.exe — это крошечная утилита, которую я написал, чтобы выполнять некоторые манипуляции со строками в JSON.
#!/bin/bash
# uses rescript
APP_KEY=_HIDDEN_
#SESSION_TOKEN=$2
HOST=https://api.betfair.com/exchange/betting
AUTHURL=https://identitysso.betfair.com/api/certlogin
CURL=curl
function bflogin()
{
echo "bflogin()"
OUT=$($CURL -s -k --cert client-2048.crt --key client-2048.key --data "username=_HIDDEN_&password=_HIDDEN_" -H "X-Application: $APP_KEY" -H "Content-Type: application/x-www-form-urlencoded" $AUTHURL)
echo $OUT
SESSION_TOKEN=$(echo $OUT | getlog.exe)
echo
echo "Here -> "$SESSION_TOKEN
echo $SESSION_TOKEN > st.txt
}
Дважды проверьте пути к вам CRT и ключевые файлы.
Кроме того, поскольку вы не указали тип кодировки ключа, по умолчанию используется PEM. Вы можете изменить тип кодировки с помощью опции CURLOPT_SSLCERTTYPE или попробовать преобразование ваших ключей в PEM.
Других решений пока нет …