PHP cURL 身份验证问题

PHP cURL Authentication Issue

我使用 HttpFox 并将值(url 和 post 数据)与我的代码生成的值进行了比较。它们完全一样,但我总是在网页上看到消息'Login failed'。我不知道可能是什么问题。

代码:

require 'domparser_1_5/simple_html_dom.php';

$username = "username";
$password = "password";

function login($url,$data){
    $fp = fopen("cookie.txt", "w");
    fclose($fp);
    $login = curl_init();
    curl_setopt($login, CURLOPT_URL, $url);
    curl_setopt($login, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($login, CURLOPT_COOKIEJAR, "cookie.txt");
    curl_setopt($login, CURLOPT_COOKIEFILE, "cookie.txt");
    curl_setopt($login, CURLOPT_TIMEOUT, 40000);
    curl_setopt($login, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($login, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
    curl_setopt($login, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($login, CURLOPT_POST, true);
    curl_setopt($login, CURLOPT_POSTFIELDS, $data);
    ob_start();
    $result = curl_exec($login);
    ob_end_clean();
    curl_close($login);
    unset($login);
    return $result;
}

function generate_pass($user, $password, $token) {
    if ($password) {
        $enc_pass = md5($password);
        $pass = $user.':'.$enc_pass.':'.$token;
        return md5($pass);
    }
}

function get_token() {
    $html = file_get_html('https://www.foo.com/');
    $token = "";
    foreach($html->find('input') as $element) {
        if($element->name == "token") {
            $token = $element->value;
        }
    }
    if (!$token) {
        die('No token found');
    }
    return $token;
}

$token = get_token();

echo login("https://www.foo.com/login/start.html", "user=".$username."&password=".$password."&submit=Anmelden&logintype=login&pid=4%2C93%2C1828&pass=".generate_pass($username, $password, $token)."&redirect_url=login%2Fstart.html&tx_felogin_pi1%5Bnoredirect%5D=0&token=".$token."");

由于 tokencookie 之间不匹配,身份验证失败。

当您加载页面以使用 get_token() 检索 令牌 时,服务器会向您发送一个您没有保存的 cookie。

稍后当您尝试登录时,服务器希望收到您收到 token 时发送给您的相同 cookie。但是你没有发送它。

我建议您使用 curl 重写 get_token() 并将 cookie 存储在 cookie.txt 中。这将使您稍后在调用 login()

时传递它们

像这样:

function get_token() {
    $url = 'https://www.foo.com/';
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_COOKIEJAR, "cookie.txt");
    curl_setopt($curl, CURLOPT_COOKIEFILE, "cookie.txt");
    curl_setopt($curl, CURLOPT_TIMEOUT, 40000);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
    $result = curl_exec($curl);
    curl_close($curl);
    unset($curl);

    $html = str_get_html( $result );
    $token = "";
    foreach($html->find('input') as $element) {
        if($element->name == "token") {
            $token = $element->value;
        }
    }
    if (!$token) {
        die('No token found');
    }
    return $token;
}

重要提示:

移除

$fp = fopen("cookie.txt", "w");
fclose($fp);

来自 login(),因为它会将 cookie.txt 文件截断为零字节,并且您不想删除刚刚检索到的 cookie。

请注意,如果指定的 cookie 文件不存在,curl_exec() 会创建它。