如何使用curl登录到Stack Exchange? [英] How can I log in to Stack Exchange using curl?

查看:68
本文介绍了如何使用curl登录到Stack Exchange?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从Terminal登录到远程网站,该网站需要用户名和密码才能登录.

因此,我首先尝试登录到Stack Exchange站点之一.根据此答案,您使用 -u用户名:密码添加凭据.>

所以我尝试了以下操作:

  USERNAME ="mine@gmail.com"PASSWORD ="myPassword"URL ="https://sustainability.stackexchange.com/"curl $ URL -u $ USERNAME:$ PASSWORD 

但是结果网站不是登录用户看到的页面,而是未经验证的用户看到的页面,其中显示注册按钮.

我认为它仅在您尝试访问它时在显示的弹出窗口中键入凭据时才起作用.

那么在这些情况下如何从Terminal内登录?

解决方案

不幸的是,登录协议比这复杂得多,并且不是内置于curl的方案.这不是curl的工作,而是某些脚本语言(例如PHP或Python),尽管libcurl将对管理http协议和cookie之类的内容有很大帮助.和libxml2将有助于解析隐藏在HTML中的登录CSRF密钥.并且他们可能需要引荐来源标头,甚至可能正在检查引荐来源标头是真实的,不是伪造的(idk,但这不会令我惊讶).

首先,向 https://sustainability.stackexchange.com/users/login 发出普通的HTTP GET请求.,并确保保存cookie和html响应.现在提取ID为 login-form 的表单的POST URL和输入元素,其中包括CSRF令牌,用户名和密码以及其他信息.然后向 https://sustainability发出 application/x-www-form-urlencoded 编码的POST请求.stackexchange.com/users/login ,其中包含从第一个GET请求收到的cookie,以及您提取的所有< input 元素的POST数据,请记住填写电子邮件"和密码"输入.

现在,您应该获取登录的html,并继续获取页面的登录版本,请确保将相同的Cookie会话ID应用于下一个http请求(该Cookie会话ID使得网站记得您是登录该帐户的那个人〜)

这是PHP中的一个示例,使用libcurl和libxml2(使用PHP的DOMDocument作为libxml2的便捷包装,并使用 getAttribute("type"),'submit')){//不知道为什么,但是浏览器在登录时会忽略按钮,即使是带有名称和值的按钮,//猜出最安全的跟随套件.继续;}//var_dump($ input-> getAttribute("type"));$ inputs [$ input-> getAttribute("name")] = $ input-> getAttribute("value");}assert(!empty($ inputs ['fkey']),'无法提取csrf令牌!');$ inputs ['email'] ='vs5jkqyx4hw3seqr@my10minutemail.com';$ inputs ['password'] ='TestingAccount123';$ hc-> setopt_array(数组(CURLOPT_POST =>真的,CURLOPT_POSTFIELDS =>http_build_query($ inputs),CURLOPT_URL =>$ url));$ hc-> exec();hhb_var_dump($ inputs,$ hc-> getStdErr(),$ hc-> getStdOut());

有趣的注释,默认情况下,libcurl在POST请求上使用 multipart/form-data -encoding,但是此站点(实际上是大多数站点)使用 application/x-www-对POST请求进行表单编码的编码.在这里,我使用PHP的http_build_query()以 application/x-www-form-urlencoded -format

格式编码POST数据

I would like to log in to a remote website from Terminal, which requires an username and password to log in.

So I first tried to log in to one of the Stack Exchange site. According to this answer, you use -u username:password to add your credentials.

So I tried the following:

USERNAME="mine@gmail.com"
PASSWORD="myPassword"

URL="https://sustainability.stackexchange.com/"
curl $URL -u $USERNAME:$PASSWORD

But the resultant website is not a page that the logged-in user sees but it is a page that non-verified user sees, which shows a Sign-up button.

I feel that it works only on the cases where you type in your credentials at the pop-ups shown when you try to access it.

So how can I log in in these cases from within Terminal?

解决方案

unfortunately, the login protocol is much more complex than that, and is not a scheme built-in to curl. this is not a job for curl, but some scripting language (like PHP or Python), though libcurl would be of great help to manage the http protocol and cookies and the likes. and libxml2 would be of help to parse out the login CSRF key, which is hidden in the HTML. and they may require a referer header, and they may even be checking that the referer header is real, not faked (idk, but it wouldn't surprise me).

first, make a plain normal HTTP GET request to https://sustainability.stackexchange.com/users/login , and make sure to save the cookies and the html response. now extract the POST URL and input elements of the form with id login-form, this includes the CSRF token, username, and password, and bunch of others. then make an application/x-www-form-urlencoded-encoded POST request to https://sustainability.stackexchange.com/users/login , with the cookies received from the first GET request, and the POST data of all the <input elements you extracted, and remember to fill out the "email" and "password" inputs.

NOW you should get the logged-in html, and to continue to get the logged-in version of the page, make sure to apply the same cookie session id to the next http requests (its this cookie session id that makes the website remember you as the guy that logged in on that account~)

here's an example in PHP, using libcurl and libxml2 (using PHP's DOMDocument as a convenience wrapper around libxml2, and using hhb_curl from https://github.com/divinity76/hhb_.inc.php/blob/master/hhb_.inc.php as a convenience wrapper around libcurl, taking care of cookies, referers, libcurl error handling (turns silent libcurl errors into exceptions, and more), at the end, it dumps the logged-in HTML, proving that it's logged in. (and the email/password provided, is a dummy account for testing, there's no problem in it being compromised, which obviously happens when i post the credentials here.):

<?php
declare(strict_types = 1);
require_once ('hhb_.inc.php');
$hc = new hhb_curl ( 'https://sustainability.stackexchange.com/users/login', true );
// getting a cookie session, CSRF token, and a referer:
$hc->exec ();
// hhb_var_dump ( $hc->getStdErr (), $hc->getStdOut () );
$domd = @DOMDocument::loadHTML ( $hc->getResponseBody () );
$inputs = array ();
$form = $domd->getElementById ( "login-form" );
$url = $form->getAttribute ( "action" );
if (! parse_url ( $url, PHP_URL_HOST )) {
    $url = 'https://' . rtrim ( parse_url ( $hc->getinfo ( CURLINFO_EFFECTIVE_URL ), PHP_URL_HOST ), '/' ) . '/' . ltrim ( $url, '/' );
}
// hhb_var_dump ( $url, $hc->getStdErr (), $hc->getStdOut () ) & die ();

foreach ( $form->getElementsByTagName ( "input" ) as $input ) {
    if (false !== stripos ( $input->getAttribute ( "type" ), 'button' ) || false !== stripos ( $input->getAttribute ( "type" ), 'submit' )) {
        // not sure why, but buttones, even ones with names and values, are ignored by the browser when logging in,
        // guess its safest to follow suite.
        continue;
    }
    // var_dump ( $input->getAttribute ( "type" ) );
    $inputs [$input->getAttribute ( "name" )] = $input->getAttribute ( "value" );
}
assert ( ! empty ( $inputs ['fkey'] ), 'failed to extract the csrf token!' );
$inputs ['email'] = 'vs5jkqyx4hw3seqr@my10minutemail.com';
$inputs ['password'] = 'TestingAccount123';
$hc->setopt_array ( array (
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => http_build_query ( $inputs ),
        CURLOPT_URL => $url 
) );
$hc->exec ();

hhb_var_dump ( $inputs, $hc->getStdErr (), $hc->getStdOut () );

interesting note, by default, libcurl uses multipart/form-data-encoding on POST requests, but this site (and most sites, really), uses application/x-www-form-urlencoded-encoding on POST requests. here i used PHP's http_build_query() to encode the POST data in in application/x-www-form-urlencoded-format

这篇关于如何使用curl登录到Stack Exchange?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆