为什么CURLOPT_COOKIEJAR以某种方式保存不同的Cookie值而不是Set-Cookie标头?

时间:2015-02-18 04:49:55

标签: php curl cookies

TL; DR:

我有一些非常简单的PHP代码,利用cURL生成单个HTTP请求(实际上,对于Diaspora * pod,尽管这与问题无关)。代码会记录Web服务器返回的任何cookie,然后手动将这些值设置为libcurl的CURLOPT_COOKIE。但是,在尝试追捕错误时,我发现当我使用CURLOPT_COOKIEFILECURLOPT_COOKIEJAR时,Cookie文件中的Cookie值与使用CURLOPT_COOKIE时的值不同。为什么会这样? (见下面的代码。)

先前研究

我已经查看了其他问题,例如this one,提出了各种方法来操纵libcurl的选项以保持相同的资源处理和内存中的cookie,但这不适合我的应用程序。我需要直接访问cookie值,特别是 not 在文件系统上(将它们保存到数据库中,但同样,这与问题无关)。

CODE

为了完整性,这是我正在使用的代码的测试用例:

<?php
// This function simply extracts the cookie set by a webserver by looking at the full HTTP source traffic.
function readCookie ($str) {
    $m = array();
    preg_match('/Set-Cookie: (.*?);/', $str, $m);
    return (!empty($m[1])) ? $m[1] : false;
}

// This function does the same for the CSRF token required for login.
function parseAuthenticityToken ($str) {
    $m = array();
    preg_match('/content="(.*?)" name="csrf-token"/', $str, $m);
    return (!empty($m[1])) ? $m[1] : false;
}

// Get first page, to find the CSRF token.
$ch = curl_init('https://diasp.org/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$resp = curl_exec($ch);
curl_close($ch);

$csrf_token = parseAuthenticityToken($resp);

$params = array(
    'user[username]' => 'my_username',
    'user[password]' => 'my_password',
    'authenticity_token' => $csrf_token
);

// Make POST request to the log in controller.
$ch = curl_init('https://diasp.org/users/sign_in');
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// In order to work, the COOKIEFILE/JAR options must be used. Why?
//curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/test_cookiejar');
//curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/test_cookiejar');
$resp = curl_exec($ch);
curl_close($resp);

$cookies = readCookie($resp);

// Even if the login is successful, this fails if and only if no COOKIEFILE/JAR is specified.
// Why?
$ch = curl_init('https://diasp.org/stream');
curl_setopt($ch, CURLOPT_COOKIE, $cookies);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// If I use COOKIEFILE here, the request works. What is this line doing that CURLOPT_COOKIE is not?
//curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/test_cookiejar');
$resp = curl_exec($ch);
curl_close($ch);

var_dump($resp);

概要

我正在对Web服务器进行非常简单,一步一步的程序调用。这些请求是一个接一个地进行的,结果输出(整个HTTP会话,包括标题)保存在一个变量中,然后读取该变量,并从Set-Cookie HTTP头解析cookie的值线。但是,如果这些行未被注释,这些值将永远不会与libcurl写入COOKIEFILE的值相同。

CURLOPT_COOKIE我做错了什么,或者我CURLOPT_COOKIEFILECURLOPT_COOKIEJAR选项正在做什么?它是以某种可逆的方式编码或解码的吗?提前谢谢。

1 个答案:

答案 0 :(得分:0)

你可能没有注意到CURLOPT_COOKIE和CURLOPT_COOKIELIST / FILE / JAR之间的区别。两者都处理cookie,但CURLOPT_COOKIE不会将您在此次设置的cookie存储在内存中,或将它们存储在CURLOPT_COOKIEJAR指定的cookie文件中; instread,CURLOPT_COOKIELIST。

libcurl中有一种称为cookie引擎的机制。当您设置CURLOPT_COOKIELIST / FILE / JAR中的任何一个时,它会被启用,libcurl负责在所有后续会话中发送/解析/读取/存储cookie。

CURLOPT_COOKIE只是一次快速设置额外cookie的方法。