php 如何使用 Curl 和 SSL 以及 cookie 登录

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10307744/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 21:52:38  来源:igfitidea点击:

How to login in with Curl and SSL and cookies

phpformscookiessslcurl

提问by Heather McVay

I been trying to log into barnesandnoble.com mobile site with curl and have had no luck so far. I get back the page with no errors and it defaults my email into the email input form box of the login page again (in the form returned from print $result).

我一直在尝试使用 curl 登录 barnesandnoble.com 移动站点,但到目前为止还没有运气。我返回没有错误的页面,它再次将我的电子邮件默认到登录页面的电子邮件输入表单框中(以从 print $result 返回的表单)。

The same code can actually let me go into ebay correctly by changing the LOGINURL to point to ebay's login

相同的代码实际上可以让我通过将 LOGINURL 更改为指向 ebay 的登录名来正确进入 ebay

The only difference being that barnesandnobles is https:// and ebay login was http://

唯一的区别是 barnesandnobles 是 https:// 而 ebay 登录是 http://

Also, I believe that barnes website is asp/aspx so I don't know how that would handle cookies and _state differently

另外,我相信 barnes 网站是 asp/aspx,所以我不知道如何以不同的方式处理 cookie 和 _state

Any help would be appreciated as I been trying to debug this for the past 16hrs

任何帮助将不胜感激,因为我一直在尝试调试过去 16 小时

also, my cookie.txt is writable and working

另外,我的 cookie.txt 是可写的并且可以工作

<?php
    $cookie_file_path = "C:/test/cookie.txt";
    $LOGINURL = "https://cart2.barnesandnoble.com/mobileacct/op.asp?stage=signIn"; 
    $agent = "Nokia-Communicator-WWW-Browser/2.0 (Geos 3.0 Nokia-9000i)";

    $ch = curl_init(); 

    $headers[] = "Accept: */*";
    $headers[] = "Connection: Keep-Alive";
    $headers[] = "Content-type: application/x-www-form-urlencoded;charset=UTF-8";

    curl_setopt($ch, CURLOPT_HTTPHEADER,  $headers);
    curl_setopt($ch, CURLOPT_HEADER,  0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_URL, $LOGINURL);
    curl_setopt($ch, CURLOPT_USERAGENT, $agent);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file_path);
    curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file_path);

    $content = curl_exec($ch); 

    curl_close($ch); 

    unset($ch); 

    // NAME="path_state" value="6657403">

    if(stristr($content,"path_state")){
        $array1 = explode('path_state" value="',$content);
        $content1 = $array1[1];
        $array2 = explode('">',$content1);
        $content2 = $array2[0];
    }

    $LOGINURL = "https://cart2.barnesandnoble.com/mobileacct/op.asp?stage=signIn";
    $POSTFIELDS = "d_hidPageStamp=V_3_17&hidViewMode=opSignIn&stage=signIn&previousStage=mainStage&path_state=" .  $content2 . "&[email protected]&acctPassword=YOURPASSWORD";
    $reffer = "https://cart2.barnesandnoble.com/mobileacct/op.asp?stage=signIn"; 

    $ch = curl_init(); 

    $headers[] = "Accept: */*";
    $headers[] = "Connection: Keep-Alive";
    $headers[] = "Content-type: application/x-www-form-urlencoded;charset=UTF-8";

    curl_setopt($ch, CURLOPT_HTTPHEADER,  $headers);
    curl_setopt($ch, CURLOPT_HEADER,  0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);   
    curl_setopt($ch, CURLOPT_URL, $LOGINURL); 
    curl_setopt($ch, CURLOPT_USERAGENT, $agent); 
    curl_setopt($ch, CURLOPT_POST, 1); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, $POSTFIELDS); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); 
    curl_setopt($ch, CURLOPT_REFERER, $reffer); 
    curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file_path); 
    curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file_path); 

    $result = curl_exec($ch);  

    print $result; 
?>

回答by drew010

Here is a working example I created from your code. This uses a function getFormFieldsthat I wrote for a similar question (first reference at the bottom of this post) which logs into the Android market.

这是我根据您的代码创建的一个工作示例。这使用了getFormFields我为登录 Android 市场的类似问题(本文底部的第一个参考)编写的函数。

I think there may have been a couple of things in your script that were preventing the login from working. First, you should urlencodethe URL parameters such as email and password in the post string (cURL will not do this for you). Second, I think the xvalue used as part of the login URL may be required.

我认为您的脚本中可能有几件事情阻止了登录工作。首先,您应该对 post 字符串中的 URL 参数(例如电子邮件和密码)进行urlencode(cURL 不会为您执行此操作)。其次,我认为x用作登录 URL 一部分的值可能是必需的。

Here is a solution that logs in successfully. Note, I re-used the original cURL handle. This is not necessary, but if you specify keep-alive, it will actually re-use the same connection, and it also saves you from having to specify the same options over and over.

这是登录成功的解决方案。请注意,我重新使用了原始的 cURL 句柄。这不是必需的,但是如果您指定 keep-alive,它实际上会重用相同的连接,并且还可以使您不必一遍又一遍地指定相同的选项。

Once you have the cookies, you can create a new cURL object and specify the COOKIEFILE and COOKIEJAR and you will be logged in without performing the first steps.

获得 cookie 后,您可以创建一个新的 cURL 对象并指定 COOKIEFILE 和 COOKIEJAR,您将无需执行第一步即可登录。

<?php

// options
$EMAIL            = '[email protected]';
$PASSWORD         = 'yourpassword';
$cookie_file_path = "/tmp/cookies.txt";
$LOGINURL         = "https://cart2.barnesandnoble.com/mobileacct/op.asp?stage=signIn"; 
$agent            = "Nokia-Communicator-WWW-Browser/2.0 (Geos 3.0 Nokia-9000i)";


// begin script
$ch = curl_init(); 

// extra headers
$headers[] = "Accept: */*";
$headers[] = "Connection: Keep-Alive";

// basic curl options for all requests
curl_setopt($ch, CURLOPT_HTTPHEADER,  $headers);
curl_setopt($ch, CURLOPT_HEADER,  0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);         
curl_setopt($ch, CURLOPT_USERAGENT, $agent); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); 
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file_path); 
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file_path); 

// set first URL
curl_setopt($ch, CURLOPT_URL, $LOGINURL);

// execute session to get cookies and required form inputs
$content = curl_exec($ch); 

// grab the hidden inputs from the form required to login
$fields = getFormFields($content);
$fields['emailAddress'] = $EMAIL;
$fields['acctPassword'] = $PASSWORD;

// get x value that is used in the login url
$x = '';
if (preg_match('/op\.asp\?x=(\d+)/i', $content, $match)) {
    $x = $match[1];
}

//$LOGINURL   = "https://cart2.barnesandnoble.com/mobileacct/op.asp?stage=signIn";
  $LOGINURL   = "https://cart2.barnesandnoble.com/mobileacct/op.asp?x=$x";

// set postfields using what we extracted from the form
$POSTFIELDS = http_build_query($fields); 

// change URL to login URL
curl_setopt($ch, CURLOPT_URL, $LOGINURL); 

// set post options
curl_setopt($ch, CURLOPT_POST, 1); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $POSTFIELDS); 

// perform login
$result = curl_exec($ch);  

print $result; 


function getFormFields($data)
{
    if (preg_match('/(<form action="op.*?<\/form>)/is', $data, $matches)) {
        $inputs = getInputs($matches[1]);

        return $inputs;
    } else {
        die('didnt find login form');
    }
}

function getInputs($form)
{
    $inputs = array();

    $elements = preg_match_all('/(<input[^>]+>)/is', $form, $matches);

    if ($elements > 0) {
        for($i = 0; $i < $elements; $i++) {
            $el = preg_replace('/\s{2,}/', ' ', $matches[1][$i]);

            if (preg_match('/name=(?:["\'])?([^"\'\s]*)/i', $el, $name)) {
                $name  = $name[1];
                $value = '';

                if (preg_match('/value=(?:["\'])?([^"\'\s]*)/i', $el, $value)) {
                    $value = $value[1];
                }

                $inputs[$name] = $value;
            }
        }
    }

    return $inputs;
}

This worked for me, hope that helps get you going.

这对我有用,希望能帮助你前进。

Here are some other cURL answer I have that may help learn:

以下是我的一些其他 cURL 答案,可能有助于学习: