PHP:发送http post请求,但;“身份验证失败”;

PHP:发送http post请求,但;“身份验证失败”;,php,http-post,Php,Http Post,我试图登录到一个网站,但收到一个“身份验证失败”错误,就好像我使用用户名或密码时出错一样。传递的参数是正确的,包括用户名和密码,因为我用Java开发了相同的代码,并且可以正常工作。我发送字段时是否出错 $cookies = array(); foreach ($http_response_header as $hdr) { if (preg_match('/^Set-Cookie:\s*([^;]+)/', $hdr, $matches)) { parse_str($ma

我试图登录到一个网站,但收到一个“身份验证失败”错误,就好像我使用用户名或密码时出错一样。传递的参数是正确的,包括用户名和密码,因为我用Java开发了相同的代码,并且可以正常工作。我发送字段时是否出错

$cookies = array();
foreach ($http_response_header as $hdr) {
    if (preg_match('/^Set-Cookie:\s*([^;]+)/', $hdr, $matches)) {
        parse_str($matches[1], $tmp);
        $cookies += $tmp;
    }
}
$cookie= reset($cookies);

$request = array(
    'http' => array(
        'method' => 'POST',
        'timeout' => 0,
        'header'=> "Accept-language: it-IT,it;q=0.8,en-US;q=0.5,en;q=0.3\r\n" .
            "Content-Type: application/x-www-form-urlencoded; charset=utf-8\r\n" .
            "User-Agent:    Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6\r\n" .
            "Cookie: ASP.NET_SessionId=".$cookie."\r\n",
        'content' => http_build_query(array(
            '__LASTFOCUS' => '',
            '__EVENTTARGET' => '',
            '__EVENTARGUMENT' => '',
            '__VIEWSTATE' => $viewstate,
            '__VIEWSTATEGENERATOR' => $viewstategenerator,
            'ctl00$hwsid' => $hwsid,
            'ctl00$PageSessionId' => $pagesessionid,
            'ctl00$DefaultUrl' => $defaulturl,
            'ctl00$GenericErrorUrl' => $genericerrorurl,
            'ctl00$PopupElement' => '',
            'ctl00$PollingTimeoutSecs' => $pollingtimeoutsecs,
            'ctl00$bodyContent$txtUser' => $user,
            'ctl00$bodyContent$txtPassword' => $password,
            '__CALLBACKID' => '__Page',
            '__CALLBACKPARAM' => '"hwsid="'.$hwsid.'"&PageSessionId="'.$pagesessionid.'"&DefaultUrl="'.$defaulturl.'"&GenericErrorUrl="'.$genericerrorurl.'"&PopupElement="'.'"&PollingTimeoutSecs="'.$pollingtimeoutsecs.'"&txtUser="'.$user.'"&txtPassword="'.$password,
            '__EVENTVALIDATION' => $eventvalidation,
            'ctl00$bodyContent$btnLogin' => 'Conferma'

        )),
    )
);

$context = stream_context_create($request);
$res= file_get_contents($url, false, $context);
echo htmlentities($res);
用于java的工作代码如下所示:

cookies = initialResponse.cookies();

                initialResponse = Jsoup.connect(url+"Default.aspx")
                    .data("__LASTFOCUS", "")
                    .data("__EVENTTARGET", "")
                    .data("__EVENTARGUMENT", "")
                    .data("__VIEWSTATE", executionVal)
                    .data("__VIEWSTATEGENERATOR", vv1)
                    .data("ctl00$hwsid", a11)
                    .data("ctl00$PageSessionId", a22)
                    .data("ctl00$DefaultUrl", a33)
                    .data("ctl00$GenericErrorUrl", a44)
                    .data("ctl00$PopupElement", "")
                    .data("ctl00$PollingTimeoutSecs", a66)
                    .data("ctl00$bodyContent$txtUser", user)
                    .data("ctl00$bodyContent$txtPassword", pass)
                    .data("__CALLBACKID", "__Page")
                    .data("__CALLBACKPARAM", "hwsid="+a11+"&PageSessionId="+a22+"&DefaultUrl="+a33+"&GenericErrorUrl="+a44+"&PopupElement="+"&PollingTimeoutSecs="+a66+"&txtUser="+user+"&txtPassword="+pass)
                    .data("__EVENTVALIDATION", ltVal)
                    .data("ctl00$bodyContent$btnLogin", "Conferma") 
                    .cookies(cookies)
                    .userAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36")
                    .method(Method.POST)
                    .timeout(0)
                    .execute();
            }catch(UnknownHostException e){
                 JOptionPane.showMessageDialog(null, "No", "Turni", JOptionPane.ERROR_MESSAGE); 
                 System.exit(0);
            } catch (IOException e) {
                e.printStackTrace();
            }

            cookies.putAll(initialResponse.cookies());

            Document doc = null;
            try {
                doc = Jsoup.connect(u)
                  .cookies(cookies)
                  .get();

            } catch (IOException e) {
                e.printStackTrace();
            }

我怀疑您误用了
reset()
。它返回第一个数组元素的值。所以,如果你要拿回不止一块饼干,你可能会遇到问题。如果您正在寻找特定的cookie,可以执行以下操作:

// here's what we're looking for
$target = "ASP.NET_SessionId";

// filter the array
$cookies = array_filter(
    $http_response_header,
    function($v) use ($target) {return strpos($v, "Set-Cookie: $target=") === 0;}
);

if (!empty($cookies)) {
    // here we know we only have a single entry in the array
    $cookie = reset($cookies);
    $cookie = preg_replace("/.*=([^;]*)/", "$1", $cookie);
} else {
    // no cookies received!
    $cookie = "";
}
事实上,这比需要的要复杂得多。最简单的方法是将所有的cookie拿到第二个请求中发送回去:

$cookies = array_filter(
    $http_response_header,
    function($v) {return strpos($v, "Set-Cookie:") === 0;}
);
$headers = [
    "Accept-language: it-IT,it;q=0.8,en-US;q=0.5,en;q=0.3",
    "Content-Type: application/x-www-form-urlencoded; charset=utf-8",
    "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6",
];
foreach ($cookies as $cookie) {
    $headers[] = preg_replace("/^Set-/", "", $cookie);
}

$request = [
    "http" => [
        "method" => "POST",
        "timeout" => 0,
        "header"=> $headers,
        "content" => "..."
];

我怀疑您误用了
reset()
。它返回第一个数组元素的值。所以,如果你要拿回不止一块饼干,你可能会遇到问题。如果您正在寻找特定的cookie,可以执行以下操作:

// here's what we're looking for
$target = "ASP.NET_SessionId";

// filter the array
$cookies = array_filter(
    $http_response_header,
    function($v) use ($target) {return strpos($v, "Set-Cookie: $target=") === 0;}
);

if (!empty($cookies)) {
    // here we know we only have a single entry in the array
    $cookie = reset($cookies);
    $cookie = preg_replace("/.*=([^;]*)/", "$1", $cookie);
} else {
    // no cookies received!
    $cookie = "";
}
事实上,这比需要的要复杂得多。最简单的方法是将所有的cookie拿到第二个请求中发送回去:

$cookies = array_filter(
    $http_response_header,
    function($v) {return strpos($v, "Set-Cookie:") === 0;}
);
$headers = [
    "Accept-language: it-IT,it;q=0.8,en-US;q=0.5,en;q=0.3",
    "Content-Type: application/x-www-form-urlencoded; charset=utf-8",
    "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6",
];
foreach ($cookies as $cookie) {
    $headers[] = preg_replace("/^Set-/", "", $cookie);
}

$request = [
    "http" => [
        "method" => "POST",
        "timeout" => 0,
        "header"=> $headers,
        "content" => "..."
];

可能有用的是查看最终URL、cookies和帖子正文;我想我已经理解了,实际上当我访问网站时,第一个cookie就会生成(ASP_NET_SessionId=wpxfk3msbyghw5nlo2wlxer),一旦你发送了带有cookie的请求帖子,网站就会发布另一个cookie来访问,我想你必须添加这个cookie(SSOAuth=DF1D63B311125E1C34689C7D16B4D798E718C1A037B189A2284797B7FFB)因此在post最终请求中,cookie将添加两个cookie“ASP_NET_SessionId=wpxfk3msbyghw5nlo2wlxer;SSOAuth=DF1D63B311125E1C34689C7D16B4D798E718C1A037B189A22847B7FFB”,但我如何输入代码并添加第二个cookie呢?查看最终的URL、cookies和帖子正文可能会有所帮助;然后将它们与工作版本进行比较。我想我已经理解了,实际上,当我访问网站时,第一个cookie就生成了(ASP_NET_SessionId=wpxfk3msbyghw5nlo2wlxer),一旦您发送了带有该cookie的请求帖子,站点将发布另一个帖子,以便能够访问,我认为您必须添加(SSOAuth=DF1D63B311125E1C34689C7D16B4B4D798E718C1A037B189A2284797B7FFB),以便在帖子最终请求中,cookie将添加两个cookie“ASP_NET_SessionId=wpxfk3msbyghw5nlo2wlxer;SSOAuth=df1d63b31125e1c34689c7d16b4be4d798e718c1a037b189a2284797b7ffb”,但如何输入代码并添加第二个cookie?更简单的方法是使用curl函数,它会自动为您处理cookie。正如我之前在访问网站时所写的,第一个cookie是生成的(ASP_NET_SessionId=wpxfk3msbyghw5nlo2wlxer),一旦您发送了带有该cookie的请求帖子,该站点将发布另一个帖子以便能够访问,我认为您必须添加(SSOAuth=df1d63b31125e1c34689c7d16b4d798e718c1a037b189a2)‌​284797B7FFB)因此,在post最终请求中,cookie将添加两个cookie“ASP_NET_SessionId=wpxfk3msbyghw5nlo2wlxer;SSOAuth=DF1D63B311125E1C34689C7D16B4BE4D798E718C1A037B189A22”‌​84797B7FFB”,但我如何进入代码并添加第二个cookie?上面的第二个代码块从响应中获取所有cookie并将它们放入您的请求中。是正确的,但在这种情况下,会将它们插入另一个get请求中。但当第二次检索所有cookie时,还有第二个cookie称为“SSOAuth”",这在POST请求中不存在。我不理解您的问题。上面的代码获取一个响应头数组并提取所有cookies。将它们放入您想要的任何请求中。更简单的方法是使用curl函数,它会自动为您处理cookies。正如我之前在访问网站时所写的,fir生成了st cookie(ASP_NET_SessionId=wpxfk3msbyghw5nlo2wlxer),一旦您发送了带有该cookie的请求帖子,站点将发布另一个cookie以便能够访问,我认为您必须添加它(SSOAuth=df1d63b31125e1c34689c7d16b4be4d798e718c1a037b189a2)‌​284797B7FFB)因此,在post最终请求中,cookie将添加两个cookie“ASP_NET_SessionId=wpxfk3msbyghw5nlo2wlxer;SSOAuth=DF1D63B311125E1C34689C7D16B4BE4D798E718C1A037B189A22”‌​84797B7FFB”,但我如何进入代码并添加第二个cookie?上面的第二个代码块从响应中获取所有cookie并将它们放入您的请求中。是正确的,但在这种情况下,会将它们插入另一个get请求中。但当第二次检索所有cookie时,还有第二个cookie称为“SSOAuth”,这在POST请求中不存在。我不理解您的问题。上面的代码获取一个响应头数组并提取所有cookie。将它们放入您想要的任何请求中。