如何使用 POCO 实现带有 HTTP 基本身份验证的 HTTP POST 请求?

4
我正在尝试使用POCO进行HTTP基本身份验证的HTTP Post(明文用户名和密码)。我找到了一个Get的示例并尝试修改它,但是由于我是新手,我认为我已经弄得一团糟。有人知道如何做到这一点吗?
是的,我已经看过关于此问题的其他SO问题:POCO C++ - NET SSL - how to POST HTTPS request,但我无法理解它如何实现用户名和密码部分。我也不理解“x-www-form-urlencoded”的用法。这是否是Post所必需的?我没有表单。只想向服务器POST使用用户名和密码参数。
3个回答

11

最后,这是你如何做到:

HTTPClientSession session("yourdomain.com");
session.setKeepAlive(true);

Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_POST, "/myapi.php/api/validate", HTTPMessage::HTTP_1_1);
req.setContentType("application/x-www-form-urlencoded");
req.setKeepAlive(true); // notice setKeepAlive is also called on session (above)

std::string reqBody("username=user1@yourdomain.com&password=mypword");
req.setContentLength( reqBody.length() );

std::ostream& myOStream = session.sendRequest(req); // sends request, returns open stream
myOStream << reqBody;  // sends the body

req.write(std::cout);

Poco::Net::HTTPResponse res;
std::istream& iStr = session.receiveResponse(res);  // get the response from server
std::cerr << iStr.rdbuf();  // dump server response so you can view it

在代码中,您明确注释了在会话和请求上使用setKeepAlive()。您是否可以编辑您的答案以解释两者的目的,以及留下其中一个或两个的效果是什么? - omatai
你为什么不使用HTTPBasicCredentials - omatai
没有特意不使用HTTPBasicCredentials的原因。当时我对很多东西并不了解。被安排去做iOS项目,同时还有其他项目在进行。稍后会回答你的第一个问题。 - Alyoshak
如果你还在附近,也许你可以帮我使用Poco Net获取授权代码。另外,感谢你在Stack Overflow上回答我的问题,我给你点赞了。 - CashCow
1
我看到你最终也回答了自己的问题 :) - CashCow
@CashCow -- 是的。事实上,我已经做过这个多次了。当你真正需要一个解决方案时,当你找到它时,你会感到有义务分享,而不仅仅是走开。正如你所看到的,这个答案已经帮助了一些人。 - Alyoshak

3
当您执行HTTP POST请求时,通常发送到服务器的数据有两种形式:
1.名称-值对,其中名称和值由“=”分隔,并且不同的对由“&”分隔。例如:var1=value1&var2=value2。此外,这些名称值对被发送以使某些特殊字符和非字母数字字符被替换为%HH,即一个百分号和两个十六进制数字,表示字符的ASCII代码。例如,如果第一个参数的值包含“#”,则会将其作为var1=value1%23&var2=value2发送。在以这种格式发送数据时,客户端需要插入一个Content-Type标头,其值为application/x-www-form-urlencoded,以便服务器正确解码数据。
2.作为多部分MIME正文,其中每个部分都可以很大并包含“未转义”的数据(包括二进制数据)。不同的MIME部分由不出现在任何MIME“有效负载”中的字符串分隔符(边界)分隔。在以这种格式发送数据时,客户端需要插入一个Content-Type标头,其值为multipart/form-data
在您提到的StackOverflow问题中,请求正文以第一种方式发送,如上所示。希望这样能够澄清问题。
祝好, Siddharth

Siddhart,这确实有点清楚了。谢谢。你用过POCO吗?如果你能提供使用POCO库成功发布带有用户名和密码的代码,我会将你的答案标记为正确的。 - Alyoshak

2

以下是 POCO 库的凭证测试代码:

HTTPRequest request;
assert (!request.hasCredentials());

HTTPBasicCredentials cred("user", "secret");
cred.authenticate(request);
assert (request.hasCredentials());
std::string scheme;
std::string info;
request.getCredentials(scheme, info);
assert (scheme == "Basic");
assert (info == "dXNlcjpzZWNyZXQ=");

HTTPBasicCredentials cred2(request);
assert (cred2.getUsername() == "user");
assert (cred2.getPassword() == "secret");

发送请求时,您只需要使用此代码的第一部分(在cred.authenticate(request)处停止)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接