如何在 C 中的 post 请求后添加给定的 cookie?

How do you add a cookie given after a post request in C?

我正在尝试创建一个为我登录网站的程序。问题是,当我遵循重定向时,网站提供了一个独特的 cookie,我不知道如何将其添加到 post 请求中。我一直在浏览手册页上的每个 libcurl 选项,但我找不到任何可以做到这一点的东西。到目前为止,这是我拥有的 post 请求功能。

void webpost(char* url, char* postdata) {

    CURL *handler = curl_easy_init();
    CURLcode err;
    long size = sizeof(postdata);

    if (handler) {
        curl_easy_setopt(handler, CURLOPT_URL, url);
        curl_easy_setopt(handler, CURLOPT_POSTFIELDSIZE, 50L); 
        curl_easy_setopt(handler, CURLOPT_POSTFIELDS, postdata); 
        curl_easy_setopt(handler, CURLOPT_FOLLOWLOCATION, 1L); 
        curl_easy_setopt(handler, CURLOPT_VERBOSE, 1L); 
        err = curl_easy_perform(handler);
        if (err != CURLE_OK) { 
            printf("ERROR POST: %s returned (%s)\n", url, curl_easy_strerror(err));
        }
        curl_easy_cleanup(handler);
    }

}

当这个函数运行时,我得到以下结果。

*   Trying 10.10.10.10...
* TCP_NODELAY set
* Connected to website.com (10.10.10.10) port 2048 (#0)
> POST /login HTTP/1.1
Host: website.com
Accept: */*
Content-Length: 50
Content-Type: application/x-www-form-urlencoded

* upload completely sent off: 50 out of 50 bytes
* Mark bundle as not supporting multiuse
< HTTP/1.1 302 Moved temporarily
< Date: Wed, 26 Aug 2020 05:59:50 GMT
< Server: EZproxy
< Expires: Mon, 02 Aug 1999 00:00:00 GMT
< Last-Modified: Wed, 26 Aug 2020 05:59:50 GMT
< Cache-Control: no-store, no-cache, must-revalidate
< Cache-Control: post-check=0, pre-check=0
< Pragma: no-cache
< Set-Cookie: ezproxy=uRZWAo3IsKyR9O0; Path=/; Domain=.website.com
< Location: http://website.com/connect?session=suRZWAo3IsKyR9O0&url=menu
< Connection: close
< 
* Closing connection 0
* Issue another request to this URL: 'http://website.com/connect?session=suRZWAo3IsKyR9O0&url=menu'
* Switch from POST to GET
* Hostname website.com was found in DNS cache
*   Trying 10.10.10.10...
* TCP_NODELAY set
* Connected to website.com (10.10.10.10) port 2048 (#1)
> GET /connect?session=suRZWAo3IsKyR9O0&url=menu HTTP/1.1
Host: website.com
Accept: */*

* Mark bundle as not supporting multiuse
< HTTP/1.1 302 Moved temporarily
< Date: Wed, 26 Aug 2020 05:59:50 GMT
< Server: EZproxy
< Expires: Mon, 02 Aug 1999 00:00:00 GMT
< Last-Modified: Wed, 26 Aug 2020 05:59:50 GMT
< Cache-Control: no-store, no-cache, must-revalidate
< Cache-Control: post-check=0, pre-check=0
< Pragma: no-cache
< Set-Cookie: ezproxy=uRZWAo3IsKyR9O0; Path=/; Domain=.website.com
< Location: http://website.com/connect?session=ruRZWAo3IsKyR9O0&url=menu
< Connection: close
< 
* Closing connection 1
* Issue another request to this URL: 'website.com/connect?session=ruRZWAo3IsKyR9O0&url=menu'
* Hostname website.com was found in DNS cache
*   Trying 10.10.10.10...
* TCP_NODELAY set
* Connected to website.com (10.10.10.10) port 2048 (#2)
> GET /connect?session=ruRZWAo3IsKyR9O0&url=menu HTTP/1.1
Host: website.com
Accept: */*

* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Wed, 26 Aug 2020 05:59:50 GMT
< Server: EZproxy
< Content-Type: text/html
< Connection: close
< 
<html>
<head>
<title>Cookie Required</title>
</head>
<body>
<p>
Licensing agreements for these databases require that access be extended
only to authorized users.  Once you have been validated by this system,
a "cookie" is sent to your browser as an ongoing indication of your authorization to
access these databases.  This cookie only needs to be set once during login.
</p>
<p>
If you are using a firewall or network privacy program, you may need
reconfigure it to allow cookies to be set from this server.
</p>
<p>
As you access databases, they may also use cookies.  Your ability to use those databases
may depend on whether or not you allow those cookies to be set.
</p>
<p>
To login again, click <a href="/login">here</a>.
</p>
</body>
</html>

* Closing connection 2

只需在下一个请求中添加 header 到与 Set-cookie: header 的 domainpath 参数匹配的站点,即:

Cookie: ezproxy=uRZWAo3IsKyR9O0

这足以让服务器识别和定位您来自的 session,因此它可以定位属于您的 session 的数据。

您可以阅读 HTTP 了解状态管理机制的描述,并阅读 CookieSet-Cookie headers。

谢谢,我可以通过将 cookie 保存到文件并在同一请求中加载它来使其正常工作。

curl_easy_setopt(处理程序, CURLOPT_COOKIEJAR, "cookies.txt"); curl_easy_setopt(处理程序, CURLOPT_COOKIEFILE, "cookies.txt");