如何在PHP中使用cURL将会话值从一个请求连续传递到另一个请求?

时间:2019-02-06 11:56:34

标签: php curl cookies

发出第一个请求时,将创建一个会话ID。相同的会话ID被传送到第二个请求。

在我的第三个请求中,为成功登录创建了一个新的会话ID,但是当我为第三个请求打印会话ID时,响应给出的是不同的会话ID。为什么会这样呢?我想将在第3个响应中获得的会话ID发送到第4个?

如何实现?

enter image description here

这是我的代码:

<?php
$fp = fopen("cookies.txt", "w");
fclose($fp);
$curl = curl_init();
curl_setopt_array($curl, array(
    CURLOPT_HEADER => TRUE,
    CURLOPT_RETURNTRANSFER => TRUE,
    CURLOPT_URL => 'https://192.168.2.35/cgi-bin/common/login/webLogin',
    CURLOPT_SSL_VERIFYPEER => false,
    CURLOPT_SSL_VERIFYHOST => false,
    CURLOPT_COOKIESESSION => TRUE,
    CURLOPT_COOKIEFILE => "cookies.txt",
    CURLOPT_COOKIEJAR => "cookies.txt",
    CURLOPT_FOLLOWLOCATION => TRUE,
    CURLOPT_AUTOREFERER => TRUE,
));
$result = curl_exec($curl);

if (!curl_exec($curl))
{
    die('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl));
}

echo "<h2>Response 1</h2>";
print_r($result);
$cookies = curl_getinfo($curl, CURLINFO_COOKIELIST);
print_r($cookies);

// #######################################################################################

$fields = array(
    'userName' => 'dadmin',
    'logonButton' => 'Logon',
    'actionStep' => 2,
);
$fields_string = http_build_query($fields);
curl_setopt_array($curl, array(
    CURLOPT_HEADER => TRUE,
    CURLOPT_RETURNTRANSFER => TRUE,
    CURLOPT_URL => 'https://192.168.2.35/cgi-bin/common/login/webLogin',
    CURLOPT_POST => TRUE,
    CURLOPT_SSL_VERIFYPEER => false,
    CURLOPT_SSL_VERIFYHOST => false,
    CURLOPT_POSTFIELDS => $fields_string,
    CURLOPT_FOLLOWLOCATION => TRUE,
    CURLOPT_COOKIESESSION => TRUE,
    CURLOPT_AUTOREFERER => TRUE,
));
$resp = curl_exec($curl);

if (!curl_exec($curl))
{
    die('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl));
}

echo "<h2>Response 2</h2>";
print_r($resp);
$cookies = curl_getinfo($curl, CURLINFO_COOKIELIST);
print_r($cookies);

// ################################################################################################

$fields = array(
    'userName' => urlencode('dadmin') ,
    'pa55word' => urlencode('dadmin01') ,
    'logonButton' => urlencode('Logon') ,
    'actionStep' => urlencode(3) ,
);
$fields_string = http_build_query($fields);
curl_setopt_array($curl, array(
    CURLOPT_HEADER => TRUE,
    CURLOPT_RETURNTRANSFER => TRUE,
    CURLOPT_URL => 'https://192.168.2.35/cgi-bin/common/login/webLogin',
    CURLOPT_POST => TRUE,
    CURLOPT_SSL_VERIFYPEER => false,
    CURLOPT_SSL_VERIFYHOST => false,
    CURLOPT_POSTFIELDS => $fields_string,
    CURLOPT_FOLLOWLOCATION => TRUE,
    CURLOPT_COOKIESESSION => TRUE,
    CURLOPT_AUTOREFERER => TRUE,
));
$response = curl_exec($curl);

if (!curl_exec($curl))
{
    die('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl));
}

echo "<h2>Response 3</h2>";
print_r($response);
echo "<br/>";
$cookies = curl_getinfo($curl, CURLINFO_COOKIELIST);
print_r($cookies);

// ###########Login Completed##################

curl_setopt_array($curl, array(
    CURLOPT_COOKIESESSION => TRUE,
    CURLOPT_HEADER => TRUE,
    CURLOPT_RETURNTRANSFER => TRUE,
    CURLOPT_URL => 'https://192.168.2.35/cgi-bin/msg/mango/admin/controller/SubscriberMgmt',
    CURLOPT_SSL_VERIFYPEER => false,
    CURLOPT_SSL_VERIFYHOST => false,
    CURLOPT_FOLLOWLOCATION => TRUE,
    CURLOPT_AUTOREFERER => TRUE,
));
$result = curl_exec($curl);

if (!curl_exec($curl))
{
    die('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl));
}

echo "<h2>Response 4</h2>";
print_r($result);
echo "<br/>";
$cookies = curl_getinfo($curl, CURLINFO_COOKIELIST);
print_r($cookies);
exit;
?>

3 个答案:

答案 0 :(得分:5)

您必须在每个请求中指定cookie文件,而不仅是在前一个或两个请求中:

CURLOPT_COOKIEFILE => "/tmp/cookies.txt",
CURLOPT_COOKIEJAR => "/tmp/cookies.txt",

还要确保文件实际上是可写的:

$cookieFile = '/tmp/cookies.txt';
if (! is_readable($cookieFile) || ! is_writable($cookieFile)) {
    throw new \Exception(
        'Cookiefile ' . $cookieFile . ' is not writable or readable.'
    );
}

答案 1 :(得分:1)

  1. 删除所有CURLOPT_COOKIESESSION => TRUE,,仅保存一个cookie,而不重写它。
  2. $fcookies = __DIR__."/cookies.txt";初始文件名
  3. 添加所有要求CURLOPT_COOKIEFILE => $fcookies, CURLOPT_COOKIEJAR => $fcookies,

解析步骤3

echo "<h2>Response 3</h2>";
print_r($response);

$new_sid = explode("sessionId=",$response);
$new_sid = explode(";",$new_sid[1]);
$new_sid = $new_sid[0];

file_put_contents($fcookies,"192.168.2.35 FALSE / TRUE 0 sessionId ".$new_sid);

echo "<br/>";
$cookies = curl_getinfo($curl, CURLINFO_COOKIELIST);
print_r($cookies);

$curl = curl_init();

Wget方式

wget --load-cookies cookie.txt --save-cookies cookie.txt -S -O step1.txt --no-check-certificate https://192.168.2.35/cgi-bin/common/login/webLogin
cat cookie.txt
wget --load-cookies cookie.txt --save-cookies cookie.txt -S -O step2.txt --post-data "userName=dadmin&logonButton=Logon&actionStep=2" --no-check-certificate https://192.168.2.35/cgi-bin/common/login/webLogin
cat cookie.txt
wget --load-cookies cookie.txt --save-cookies cookie.txt -S -O step3.txt --post-data "userName=dadmin&pa55word=dadmin01&logonButton=Logon&actionStep=3" --no-check-certificate https://192.168.2.35/cgi-bin/common/login/webLogin
cat cookie.txt
wget --load-cookies cookie.txt --save-cookies cookie.txt -S -O step4.txt --post-data "motdContinue=Continue&actionStep=motdContinue" --no-check-certificate https://192.168.2.35/cgi-bin/common/loginMotd/w_motd
cat cookie.txt
wget --load-cookies cookie.txt --save-cookies cookie.txt -S -O step5.txt --no-check-certificate https://192.168.2.35/cgi-bin/msg/mango/admin/controller/SubscriberMgmt
cat cookie.txt

答案 2 :(得分:1)

因为您反复告诉curl丢弃所有现有的会话Cookie, 这是CURLOPT_COOKIESESSION上的php文档:

  

TRUE,以将其标记为新的cookie“会话”。它将强制libcurl忽略上一个会话中将要加载的所有“会话cookie” cookie。默认情况下,libcurl始终存储和加载所有cookie,无论是否为会话cookie,它们都是独立的。会话cookie是没有有效期限的cookie,并且仅在此“会话”中存在并且存在。

  • 每次设置CURLOPT_COOKIESSION时,您告诉curl丢弃所有现有的会话cookie ,并为每个呼叫进行设置。实际上,您根本不需要设置它,除非您想清除cookie罐中的旧的现有退出cookie。只需删除对CURLOPT_COOKIESESSION的所有引用-如果您的旧Cookie已过期,服务器将在curl_exec()中为您提供一个新会话。

您做错了吗

$fields = array(
    'userName' => urlencode('dadmin') ,
    'pa55word' => urlencode('dadmin01') ,
    'logonButton' => urlencode('Logon') ,
    'actionStep' => urlencode(3) ,
);
$fields_string = http_build_query($fields);

在此,用户名/密码/等将被双重urlencoded。该代码应显示为:

$fields = http_build_query(array(
    'userName' => 'dadmin',
    'pa55word' => 'dadmin01',
    'logonButton' => 'Logon',
    'actionStep' => 3,
));

因为http_build_query确实进行url编码,所以http_build_query实际上是这样实现的:

function http_build_query(array $data):string{
    $ret='';
    foreach($data as $key=>$val){
        $ret.=urlencode($key)."=".urlencode($data)."&";
    }
    $ret=substr($ret,0,-1);
    return $ret;
}