【问题标题】:Passing multiple POST request parameters C++ libcurl传递多个 POST 请求参数 C++ libcurl
【发布时间】:2021-02-23 20:45:07
【问题描述】:

目前使用 libcurl 的 C++ 实现与 Spotify API 交互,寻找一种在 POST 请求期间传递多个“请求正文参数”的方法。必填字段为:

查看libcurl的文档中找到的example of a POST request,似乎是这一行:

curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "name=daniel&project=curl");

传递两个参数:“名称”和“项目”。当我使用 Spotify 的 API 尝试类似的格式时:

curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "grant_type=authorization_code&code=abcdef&redirect_uri=example.com");

我收到以下错误:

{"error":"unsupported_grant_type","error_description":"grant_type parameter is missing"}

我已经验证了CURLOPT_POSTFIELDS 适用于这种情况,只传递了"grant_type",因为API 响应告诉我我的请求缺少代码,所以很明显API 正在读取POSTFIELDS 参数。

有人知道如何在POST 请求中包含多个参数吗?

编辑:提供一个最小的可重现示例: 作为 oAuth 流程的一部分,此示例发生在用户收到 oAuth 访问令牌之后

CURL *curl;
std::string res;

curl = curl_easy_init();
    
if(curl) {
    try {
        curl_easy_setopt(curl, CURLOPT_TCP_NODELAY, 0);
        curl_easy_setopt(curl, CURLOPT_URL, "https://accounts.spotify.com/api/token");

        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "grant_type=authorization_code&code=abcdef&redirect_uri=example.com");     
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &res);

        std::string enc = base64_encode(reinterpret_cast<const unsigned char*>((myClientID + ":" + myClientSecret).data()), (myclientID + ":" + myClientSecret).length(), false);
            
        std::string httpAuth = "Authorization: Basic " + enc;
        struct curl_slist *authChunk = nullptr;
        authChunk = curl_slist_append(authChunk, httpAuth.c_str());

        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, authChunk);

        curl_easy_perform(curl);
        curl_easy_cleanup(curl);
    }
    catch (const char* Exception) {
        std::cerr << Exception << std::endl;
    }
}

【问题讨论】:

  • 您的curl_easy_setopt() 调用对我来说看起来不错,假设您在真实代码中使用正确的coderedirect_uri。您将必须提供minimal reproducible example。 Spotify API 提供了curl 示例,这些示例很容易转换为 libcurl。
  • 添加了示例。是的,code 和 redirect_uri 是我实际代码中的有效参数。我最初将 Python 用于此授权流程,但决定在我正在处理的项目的上下文中迁移到 C++。我一直在使用 Spotify API curl 示例,它们在将我的代码从 Python 请求调用转换为 C++ libcurl 方面提供了巨大帮助。 curl_easy_setopt() 似乎是正确的,并且遵循 Spotify 提供的 curl 示例,但我一直遇到上面显示的错误。
  • 根据Spotify's Authorization Guide,您不能向/api/token 发送请求,直到您首先向/authorize 发送请求以获得所需的授权code,然后您可以将其提供给@ 987654341@。您的示例没有执行第一步,除非您从程序的早期运行中获得了 code 并尝试刷新其到期日期(但随后 grant_type 需要改为 "refresh_token")。跨度>
  • 另外,this&gt;WriteCallback(应该是this-&gt;WriteCallback)意味着WriteCallback 是一个非static 类方法,对吗?您不能将非static 类方法与CURLOPT_WRITEFUNCTION 一起使用。您需要改用static 方法,使用CURLOPT_WRITEDATA 传递this 指针。
  • 在 this->WriteCallback 上:我的代码中有正确的语法,但在删除代码示例的个人信息时错过了这一点。考虑到我一直在非静态方法中使用 WriteCallback,我很感兴趣我的其他 libcurl 用途如何在其他用例中工作,但这是另一个问题。至于这个代码块的逻辑流程,这个例子发生在“用户”收到代码之后

标签: c++ api curl spotify libcurl


【解决方案1】:

对于遇到此问题的任何人 - 确保在格式化 POST 请求时正确编码 redirect_uri 参数。以下是我的不同做法

// Wrote a custom URL encoding function

std::string urlEncEasy(std::string url) {
    std::string res;

    for (auto c : url) {
        if (c == ':') {
            res += "%3A";
        }
        else if (c == '/') {
            res += "%2F";
        }
        else {
            res += c;
        }
    } 
    return res;
}

// Changed my CURLOPT_POSTFIELDS to
std::string postFields = "grant_type=authorization_code&code=" + myAuthToken + "&redirect_uri=" + urlEncEasy(myRedirectUri);

curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postFields.c_str());     

【讨论】:

  • 你的url编码功能不完整,有很多字符没有编码。 libcurl 有一个 curl_easy_escape() 函数用于 url 编码字符串。
猜你喜欢
  • 2016-01-25
  • 2023-01-13
  • 1970-01-01
  • 1970-01-01
  • 2019-08-03
  • 2014-02-26
  • 2016-11-05
  • 2013-08-09
  • 2021-10-13
相关资源
最近更新 更多