【问题标题】:HTTP GET request with boost c++ - oauth2 access token带有 boost c++ 的 HTTP GET 请求 - oauth2 访问令牌
【发布时间】:2016-11-16 21:51:08
【问题描述】:

我需要从一个 c++ 应用程序连接到一个休息服务器,我的问题是发送服务器提供的令牌访问时。

我尝试了多种方法,但找不到正确的语法。

其余服务器使用oauth2进行认证,token类型为bearer。

在 oauth1 中我发现了这个语法:

std::ostream request_stream(&request_);
request_stream << "GET " << path << " HTTP/1.0\r\n";
request_stream << "Host: " << server << "\r\n";
request_stream << "Content-Type: application/x-www-form-urlencoded\r\n";
request_stream << "Authorization: OAuth oauth_version=\"1.0\", "
<< oauth_signature_method=\"PLAINTEXT\", "
<<"oauth_consumer_key=\"<key>\", "
<<"oauth_signature=\"<secret>&\"\r\n";
request_stream << "Accept: */*\r\n";
request_stream << "Connection: close\r\n\r\n";

但是对于 oauth2,我找不到正确的语法。

在我所做的所有尝试中,我将突出显示 2 个:

1.

std::ostream request_stream(&request_);
request_stream << "GET " << path << " HTTP/1.0\r\n";
request_stream << "Host: " << server << "\r\n";
request_stream << "Authorization: Bearer accesstoken\r\n";
request_stream << "Accept: */*\r\n";
request_stream << "Connection: close\r\n\r\n";

错误返回:“异常:未指定的文件(1):未终止的字符串”

2.

std::ostream request_stream(&request_);
request_stream << "GET " << path << " HTTP/1.0\r\n";
request_stream << "Host: " << server << "\r\n";
request_stream << "Content-Type: application/x-www-form-urlencoded\r\n";
request_stream << "Authorization: OAuth oauth_version=\"2.0\", "
<<"oauth_token_type=\"Bearer\", "
<<"oauth_access_token=\"accesstoken\"\r\n";
request_stream << "Accept: */*\r\n";
request_stream << "Connection: close\r\n\r\n";

返回错误:“返回响应,状态码为 401”

另外,尝试在这两种情况下都在行尾不带“\r\n”,但它不起作用。

request_stream << "Authorization: Bearer accesstoken";

request_stream << "Authorization: OAuth oauth_version=\"2.0\", "
<<"oauth_token_type=\"Bearer\", "
<<"oauth_access_token=\"accesstoken\"";

我需要请求“授权”的正确文本字符串才能将访问令牌发送到服务器:

request_stream << "Authorization: ??????? \r\n";

有人知道发送访问令牌的正确语法吗?

谢谢!!

已编辑 - 11 月 18 日

忘了说其余服务器是用 symfony2 和 fosrestbundle 制作的。显然 fosrestbundle 需要很好地了解它才能正确配置服务,否则会出现问题。

现在我正在使用 symfony3 和 firebase-jwt 测试 rest。我想我不会有问题,因为我可以配置几乎所有东西,而不必在外部捆绑中走这么远。

我没有尝试过 symfony3 和 fosrestbundle,但似乎 fosrestbundle 需要了解它才能正确配置。

当我说需要有关此捆绑包的更高级知识时,这是因为它在我所做的其他应用程序(例如 android 应用程序)中非常适合我;但是从一个 c++ 应用程序给我带来了问题。

我希望这些信息对某人有用

11 月 21 日编辑

我尝试使用 symfony3 和 firebase-jwt,但它一直给我同样的错误。

我错了 fosrestbundle,实际上两个服务器(fosrestbundle 和 symfony3-jwt)都进行身份验证并正确发送客户端请求的数据。

问题出在客户端:

void Restclient::handle_read_content(const boost::system::error_code& err)
{
    if (!err)
    {
        std::ostringstream ss;
        ss << &response_;
        std::string s = ss.str();
        boost::property_tree::ptree pt2;
        stringstream is (s);
        boost::property_tree::read_json (is, pt2);

        boost::asio::async_read(socket_, response_, boost::asio::transfer_at_least(1), boost::bind(&Restclient::handle_read_content, this, boost::asio::placeholders::error));
    }
    else if (err != boost::asio::error::eof)
    {
        std::cout << "Error: " << err << "\n";
    }
}

在执行了几次测试后,我验证了正是在这一行中发生了错误:

boost::property_tree::read_json (is, pt2);

json 顺利到达:(例如)

{ "Data1": "c ++", "data2": "java", "data3": "python", "data4": "php", "data5": "c #"}

我不打算放实际的 json,因为它是一个很长的字符串,但这只是为了给你一个想法。

在读取并转换为 json 的那一刻,会出现这样的情况:

{ "Data1": "c ++", "data2": "java", "data3": "python", "dat
Exception: <unspecified file> (1): unterminated string

我在这里公开的代码是基于 boost c++ async_client 的示例,但它给了我这个问题。

如果有人解决了这个问题,我会很感激你的帮助。

编辑 - 11 月 27 日 [已解决]

std::ostream request_stream(&request_);
request_stream << "GET " << path << " HTTP/1.0\r\n";
request_stream << "Host: " << server << "\r\n";
request_stream << "Authorization: Bearer accesstoken\r\n";
request_stream << "Accept: */*\r\n";
request_stream << "Content-Length: 0\r\n\r\n";

void Restclient::handle_read_content(const boost::system::error_code& err)
{
    if (!err)
    {
        boost::system::error_code error;
        string result = "";
        //Read the answer to the end
        while (boost::asio::read(socket_, response_, boost::asio::transfer_at_least(1), error))
        {
            std::ostringstream ss;
            ss << &response_;
            std::string output = ss.str();
            result = result + output;
        }

        //If the answer has already arrived and there is nothing left to read
        if (error == boost::asio::error::eof)
        {
            stringstream is (result);
            boost::property_tree::ptree pt2;
            boost::property_tree::read_json (is, pt2);
        }
        boost::asio::async_read(socket_, response_, boost::asio::transfer_at_least(1), boost::bind(&Restclient::handle_read_content, this, boost::asio::placeholders::error));
    }
    else if (err != boost::asio::error::eof)
    {
        std::cout << "Error: " << err << "\n";
    }
}

JSON 完整,ptree 生成正确

【问题讨论】:

  • 调试此类事情的一种简单方法是使用一个库来尝试它,该库提供了与 OAuth2 一起使用的简单 API,例如:python。如果你得到这个工作,那么使用任何跟踪工具很容易找出该库在标头中发送的内容

标签: c++ http boost token oauth2


【解决方案1】:

您有一些HTTP 格式问题。

您的请求都没有发送消息正文的大小(在您的情况下为零),并且由于您发送 HTTP 1.0 请求,因此无需发送 Connection: close,服务器应在连接后关闭连接发送了它的响应。如果您不想要这种行为,请将HTTP/1.0 更改为HTTP/1.1

尝试替换尝试2的最后一行:

request_stream << "Connection: close\r\n\r\n";

与:

request_stream << "Content-Length: 0\r\n\r\n";

您应该会收到200(正常)或401(未经授权)响应。

仅供参考,语法在 HTTP 规范中定义,RFC7230,特别是 RFC7235 用于身份验证。

【讨论】:

    猜你喜欢
    • 2016-05-10
    • 2019-06-04
    • 1970-01-01
    • 1970-01-01
    • 2016-04-02
    • 2011-03-22
    • 2018-09-02
    • 2015-11-27
    • 2014-12-15
    相关资源
    最近更新 更多