#c #twitter #http-headers #twitter-oauth #libcurl
#c #Twitter #http-заголовки #twitter-oauth #libcurl
Вопрос:
Я пытаюсь опубликовать твит в Twitter со следующим кодом, но продолжаю получать сообщение об ошибке «Не удалось аутентифицировать вас», «code»: 32″:
curl_global_init(CURL_GLOBAL_ALL);
CURL *curl = curl_easy_init();
char *signedurl = malloc(sizeof(char) * 1024); /* Not how it will be, but works in this example. */
char *url = "https://api.twitter.com/1.1/statuses/update.json";
signedurl = oauth_sign_url2(url, NULL, OA_HMAC, "POST", consumer_key, consumer_secret, user_token, user_secret);
char *status = "status=test";
curl_easy_setopt(curl, CURLOPT_URL, signedurl); /* URL we're connecting to, after being signed by oauthlib */
curl_easy_setopt(curl, CURLOPT_USERAGENT, "dummy-string"); /* Not the actual string, just a dummy for this example */
curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, status);
//curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
int curlstatus = curl_easy_perform(curl); /* Execute the request! */
curl_easy_cleanup(curl);
free(signedurl);
Теперь я просмотрел документацию Twitter и обсуждение на их веб-сайте, и они рекомендуют три вещи:
- Восстановите свои токены доступа. Я сделал это и попытался опубликовать в Twitter через них, используя консоль разработчиков в моей настольной программе Twitter, и это работает. Это заставляет меня думать, что проблема кроется в другом.
- Включить
Content-Type: application/x-www-form-urlencoded
в заголовок запроса. Насколько я понимаю, это значение по умолчанию для того, как я использую cURL, и действительно, когда я используюVERBOSE
опцию, я вижу, что она находится в заголовке. - Правильно закодируйте URL-адрес. Я знаю, что это
oauth_sign_url2
делает это правильно при извлечении данных из Twitter, и я пробовал использоватьoauth_url_escape("status=test")
для статуса (хотя я не думаю, что я должен это делать). Это тоже не работает.
У меня такое чувство, что это что-то совершенно очевидное, но я в тупике.
Комментарии:
1. Работает ли ваш запрос, если вы выполняете его с помощью
curl
инструмента командной строки?2. @ ams Это был очень хороший вопрос. Я использовал инструмент, предоставляемый Twitter, для генерации команды для меня, просто чтобы быть уверенным, что это сработает, и, между прочим, я получаю то же сообщение об ошибке. Конечно, это означает, что проблема в их конце?
3. Я попробовал еще раз, и, к сожалению, я хочу сказать, что это прошло. Я понятия не имею, что тогда было по-другому.
4. Кто знает, может быть, происходит какая-то блокировка от злоупотреблений? В любом случае, если проблема устранена, все хорошо. 🙂
5. Что ж, код по-прежнему не работает. Это работает только тогда, когда я использую инструмент командной строки.
Ответ №1:
Чего не хватало в моем исходном коде, так это правильного построения заголовка. Работает следующий код.
char *ttwytter_request(char *http_method, char *url, char *url_enc_args)
{
struct curl_slist * slist = NULL;
char * ser_url, **argv, *auth_params, auth_header[1024], *non_auth_params, *final_url, *temp_url;
int argc;
ser_url = (char *) malloc(strlen(url) strlen(url_enc_args) 2);
sprintf(ser_url, "%s?%s", url, url_enc_args);
argv = malloc(0);
argc = oauth_split_url_parameters(ser_url, amp;argv);
free(ser_url);
temp_url = oauth_sign_array2(amp;argc, amp;argv, NULL, OA_HMAC, http_method, consumer_key, consumer_secret, user_token, user_secret);
free(temp_url);
auth_params = oauth_serialize_url_sep(argc, 1, argv, ", ", 6);
sprintf( auth_header, "Authorization: OAuth %s", auth_params );
slist = curl_slist_append(slist, auth_header);
free(auth_params);
non_auth_params = oauth_serialize_url_sep(argc, 1, argv, "", 1 );
final_url = (char *) malloc( strlen(url) strlen(non_auth_params) );
strcpy(final_url, url);
postdata = non_auth_params;
for (int i = 0; i < argc; i )
{
free(argv[i]);
}
free(argv);
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_USERAGENT, "dummy-string");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postdata);
int curlstatus = curl_easy_perform(curl); /* Execute the request! */
curl_easy_cleanup(curl);
}