简体   繁体   English

如何在单个cURL请求中获取和发布信息?

[英]How to get and post information in a single cURL request?

Is it possible to get the value of an input and also post information in the same cURL request? 是否可以获取inputvalue并在同一cURL请求中post信息?

Reason: I am trying to login here using cURL, however, the login form generates a unique key in the value of the input named form_key . 原因:我试图使用cURL登录此处 ,但是登录表单会在名为form_keyinput value中生成一个唯一键。 So, I want to first get that value then post the username and password to successfully login. 因此,我想首先获取该值,然后发布用户名和密码以成功登录。

PHP (not working, gives a blank page with nothing in source code): PHP(无法正常工作,在空白页中没有源代码):

$ch2 = curl_init();
curl_setopt($ch2, CURLOPT_URL, "https://b2b.chiemsee.com/customer/account/login/");
curl_setopt($ch2, CURLOPT_FOLLOWLOCATION, true); // to allow redirections
//curl_setopt($ch2, CURLOPT_SSL_VERIFYPEER, FALSE); // to avoid error
curl_setopt($ch2, CURLOPT_POST, true); // to send info
curl_setopt($ch2, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch2, CURLOPT_COOKIEJAR, 'cookie.txt'); // to save cookie data for login
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true); // to get the html
$response2 = curl_exec($ch2);
curl_close($ch2);

$html = new simple_html_dom();
$html->load($response2);

$val = $html->find('input[name=form_key]');
$form_key = $val[0]->value;

$data = array(
    'form_key' => $form_key,
    'login[username]' => 'myusername',
    'login[password]' => 'mypassword',
    'send' => '',
);

PS When I login manually and check the browser console -> network -> post -> headers/parameters, I get the following:- PS当我手动登录并检查浏览器控制台->网络->发布->标头/参数时,得到以下信息:

form_key: viiRqZigH0YPC9wu
login[username]: myusername
login[password]: mypassword
send: 

UPDATE. UPDATE。 TWO SEPARATE cURL REQUESTS (still now working): 两个单独的cURL请求(现在仍然有效):

include('simple_html_dom.php'); 包括( 'simple_html_dom.php');

$ch2 = curl_init();
curl_setopt($ch2, CURLOPT_URL, "https://b2b.chiemsee.com/customer/account/login/");
curl_setopt($ch2, CURLOPT_FOLLOWLOCATION, true); // to allow redirections
curl_setopt($ch2, CURLOPT_COOKIEJAR, 'cookie.txt'); // to save cookie data for login
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true); // to get the html
$response2 = curl_exec($ch2);
curl_close($ch2);

$html = new simple_html_dom();
$html->load($response2);

$val = $html->find('input[name=form_key]');
$form_key = $val[0]->value;

$data = array(
    'form_key' => $form_key,
    'login[username]' => 'myusername',
    'login[password]' => 'mypassword',
    'send' => 'Anmelden'
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://b2b.chiemsee.com/customer/account/login/");
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // to allow redirections
//curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // to avoid error
curl_setopt($ch, CURLOPT_POST, true); // to send info
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt'); // to read data
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // to get the html
$response = curl_exec($ch);
if (curl_error($ch)) {
    $error_msg = curl_error($ch);
    var_dump($error_msg);
    exit;
}
curl_close($ch);
echo $response;

So a bit of an intro of what's going on. 因此,介绍一下正在发生的事情。

form_key seems to be used as a form of CSRF protection specifically it is a synchronizer token . form_key似乎用作CSRF保护的一种形式,特别是它是一个同步令牌

In short what happens is, a user visits a web page, the web page creates a session for the user and generates a unique token. 简而言之,发生的情况是,用户访问网页,该网页为该用户创建会话并生成唯一令牌。 The server then attaches that unique token to the form as a hidden field. 然后,服务器将该唯一令牌作为隐藏字段附加到表单。 When a user submits that form then it is submitted with that hidden field and the server can cross-reference that the token received is the same as the one that was sent. 当用户提交该表单时,它将与该隐藏字段一起提交,并且服务器可以交叉引用接收到的令牌与发送的令牌相同。

However the critical part is that the server needs to be aware of who the user is, and that is done through the session. 但是,关键部分是服务器需要知道用户是谁,而这是通过会话完成的。 The session is maintained via a session cookie, which is why the session cookie is necessary. 通过会话cookie维护会话,因此需要会话cookie。

To correctly simulate a real user you need to store the cookies the server sends you on first visit, this is done using the CURLOPT_COOKIEJAR : 为了正确模拟真实用户,您需要存储服务器在第一次访问时发送给您的cookie,这可以使用CURLOPT_COOKIEJAR来完成:

$ch2 = curl_init();
curl_setopt($ch2, CURLOPT_URL, "https://b2b.chiemsee.com/customer/account/login/");
curl_setopt($ch2, CURLOPT_FOLLOWLOCATION, true); // to allow redirections
//curl_setopt($ch2, CURLOPT_SSL_VERIFYPEER, FALSE); // to avoid error
curl_setopt($ch2, CURLOPT_POST, true); // to send info
curl_setopt($ch2, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch2, CURLOPT_COOKIEJAR, 'cookie.txt'); // to save session cookie
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true); // to get the html
$response2 = curl_exec($ch2);
curl_close($ch2);

after you've done this and retrieved the CSRF token by scraping the page you need to submit this along with the corresponding cookies: 完成此步骤并通过抓取页面检索CSRF令牌后,您需要将其与相应的Cookie一起提交:

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://b2b.chiemsee.com/customer/account/loginPost/"); //Make sure you have the correct URL
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // to allow redirections
//curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // to avoid error
curl_setopt($ch, CURLOPT_POST, true); // to send info
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt'); // to read cookie data
curl_setopt($ch2, CURLOPT_COOKIEJAR, 'cookie.txt'); // optional, this will update existing cookies and add new ones if needed.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // to get the html
$response = curl_exec($ch);
if (curl_error($ch)) {
    $error_msg = curl_error($ch);
    var_dump($error_msg);
    exit;
}
curl_close($ch);
echo $response;

This should allow the server to load the correct session for which the CSRF token was created in the first place and then verify that token you're sending. 这应该允许服务器首先加载为其创建CSRF令牌的正确会话,然后验证您要发送的令牌。

As a sidenote: The reason for the token is simple. 附带说明:令牌的原因很简单。 If I make a webpage which tricks users to post directly to another webpage this token is a piece of data that I can never have access to as it is only shared with the user directly so 3rd parties can't access it. 如果我制作的网页欺骗用户直接发布到另一个网页,则该令牌是我永远无法访问的数据,因为它仅与用户直接共享,因此第三者无法访问它。 It might make automations such as yours harder to implement but it is very effective for user security. 它可能会使像您这样的自动化系统难以实施,但对于用户安全性非常有效。

What you're asking is not possible. 您的要求是不可能的。 Not because of cURL or PHP limitations, but simply because of causality. 不是因为cURL或PHP的限制,而是因为因果关系。 Consider the logical set of steps being performed. 考虑正在执行的逻辑步骤集。 In order to send the login request, you must first know the form_key . 为了发送登录请求,您必须首先知道form_key In order to know the form_key you must first request the login page. 为了知道form_key您必须首先请求登录页面。

To put it simply, you can't make use of information that you don't have yet. 简而言之,您无法利用尚未拥有的信息。

  • Make the first HTTP request to get the form information. 发出第一个HTTP请求以获取表单信息。 (Specifically the form_key value that you need.) (特别是您需要的form_key值。)
  • Make the second HTTP request to send the login information, including the data you fetched from the first request. 发出第二个HTTP请求以发送登录信息,包括您从第一个请求中获取的数据。

There's no reason to try to do this in a single step. 没有理由试图一步一步地做到这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM