错误:在Dropbox上上传文件时出现无效签名
我正在尝试开发使用Dropbox的桌面应用程序。我使用C++,libcurl(用于请求)liboauthcpp(用于身份验证)和Rest API(来自Dropbox)。错误:在Dropbox上上传文件时出现无效签名
由于我已经成功验证和一些更多的操作(列表和下载文件),我无法管理上传文件。我收到以下错误:{ “错误”: “无效的签名”}
这里是我的代码:
m_upload_url = "https://api-content.dropbox.com/1/files/sandbox/";
OAuth::Consumer consumer(m_consumer_key, m_consumer_secret);
OAuth::KeyValuePairs access_token_resp_data = OAuth::ParseKeyValuePairs(m_access_token_Response);
OAuth::Token access_token = OAuth::Token::extract(access_token_resp_data);
OAuth::Client oauth = OAuth::Client(&consumer, &access_token);
string oAuthQueryString = oauth.getURLQueryString(OAuth::Http::Post, m_upload_url);
string upload_Request = (string(m_upload_url) + string("?") + oAuthQueryString);
CURL *curl;
CURLcode res;
struct curl_httppost *formpost=NULL;
struct curl_httppost *lastptr=NULL;
struct curl_slist *headerlist=NULL;
static const char buf[] = "Expect:";
curl_global_init(CURL_GLOBAL_ALL);
/* Fill in the file upload field */
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "file",
CURLFORM_FILE, "C:/Users/Desktop/textfile.txt",
CURLFORM_END);
/* Fill in the filename field */
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "name",
CURLFORM_COPYCONTENTS, "textfile",
CURLFORM_END);
/* Fill in the submit field too, even if this is rarely needed */
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "submit",
CURLFORM_COPYCONTENTS, "send",
CURLFORM_END);
curl = curl_easy_init();
/* initalize custom header list (stating that Expect: 100-continue is not
wanted */
headerlist = curl_slist_append(headerlist, buf);
if(curl) {
/* what URL that receives this POST */
curl_easy_setopt(curl, CURLOPT_URL, upload_Request.c_str());
/* only disable 100-continue header if explicitly requested */
curl_easy_setopt(curl, CURLOPT_HTTPPOST, 1L);
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeFunction);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
/* Perform the request, res will get the return code */
res = curl_easy_perform(curl);
string response = string(gData);
qDebug() << QString::fromStdString(response);
/* Check for errors */
if(res != CURLE_OK)
qDebug() << "curl_easy_perform() failed: %s\n" << curl_easy_strerror(res);
/* always cleanup */
curl_easy_cleanup(curl);
/* then cleanup the formpost chain */
curl_formfree(formpost);
/* free slist */
curl_slist_free_all (headerlist);
}
这里是WRITEFUNCTION:
char gData[1024*1024];
unsigned int gDataLen = 0;
size_t writeFunction(char *ptr, size_t size, size_t nmemb)
{
memcpy(&(gData[gDataLen]), ptr, (size * nmemb));
gDataLen += (size * nmemb);
gData[ gDataLen ] = '\0';
return (size * nmemb);
}
任何想法,请?
编辑:
我与明文方法produse和请求: {“error”:“签名无效。”}
您使用的是哪种OAuth签名方法?如果它不是纯文本,那么我相信问题在于你没有将HTTP请求的主体传递给getURLQueryString
。身体需要成为已签名字符串的一部分。这就解释了为什么你能够获得几个GET
的操作;这些请求没有一个机构。
附注:它看起来像你使用POST形式的文件上传,其中as the docs say比PUT复杂得多。我认为如果你改变你的生活会更好。 :-)例如,我认为您添加的submit
字段可能会导致呼叫无法正常工作。
编辑:这是一个使用手动构建的明文签名的完整工作示例。填写应用程序键,应用程序的秘密,令牌和令牌密钥,并确保有一个名为“hello.txt的”这个工作文件:
#include <stdio.h>
#include <curl/curl.h>
#include <iostream>
#include <fstream>
using namespace std;
size_t read_data(void *ptr, size_t size, size_t nmeb, void *stream)
{
return fread(ptr,size,nmeb,(FILE*)stream);
}
int main(void)
{
CURL *curl;
CURLcode res;
FILE * rfp = fopen("hello.txt", "r");
string appkey = "<APP KEY>";
string appsecret = "<APP SECRET>";
string token = "<ACCESS TOKEN>";
string token_secret = "<ACCESS TOKEN SECRET>";
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_URL, "https://api-content.dropbox.com/1/files_put/sandbox/hello.txt");
struct curl_slist *headers = NULL;
string header = "Authorization: OAuth oauth_version=\"1.0\", oauth_signature_method=\"PLAINTEXT\", oauth_consumer_key=\"" + appkey + "\", oauth_token=\"" + token + "\", oauth_signature=\"" + appsecret + "&" + token_secret + "\"";
headers = curl_slist_append(headers, header.c_str());
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_PUT, 1L);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_data);
curl_easy_setopt(curl, CURLOPT_READDATA, rfp);
res = curl_easy_perform(curl);
curl_slist_free_all(headers);
if(res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n",
curl_easy_strerror(res));
curl_easy_cleanup(curl);
}
fclose(rfp);
return 0;
}
有没有人用过liboauthcpp?我怀疑我的错误是在我使用getURLQueryString的方式..我传递的URL到这个函数,但我不知道我是否也必须传递数据。 不幸的是,这个库没有文档。
这就是我的答案指出的。您的代码不会将HTTP请求的主体传递给'getURLQueryString'。 – smarx
我觉得我通过HTTP请求的身体传递getURLQueryString,通过编写: – michalis
请查看我的编辑 – michalis
我也尝试过“PUT”,但我仍然得到相同的错误。 – michalis