如何使用curl登录Stack Exchange?

时间:2017-05-24 09:26:07

标签: curl credentials

我想从终端登录远程网站,这需要用户名和密码才能登录。

所以我首先尝试登录其中一个Stack Exchange站点。 According to this answer,您使用-u username:password添加凭据。

所以我尝试了以下内容:

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

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

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

我觉得它仅适用于您在尝试访问时显示的弹出窗口中输入凭据的情况。

那么如何从终端内登录这些情况?

4 个答案:

答案 0 :(得分:7)

您可以通过浏览器工具完成。您需要通过Chrome浏览器复制包含所有标题的Cookie>查看> Javascript控制台>网络> (右键单击)>复制选项菜单>单击选择“复制为cURL”:

enter image description here

通常我们会这样卷曲:

curl -c cookie.txt -d "LoginName=username" -d "password=changepassword" https://examplesite/a
curl -b cookie.txt https://examplesite/b

通过右键单击复制将非常大(当然我改变了一些东西以防止自己被黑客入侵):

curl 'https://meta.stackoverflow.com/' -H 'pragma: no-cache' -H 'accept-encoding: gzip, deflate, sdch, br' -H 'accept-language: en-US,en;q=0.8' -H 'upgrade-insecure-requests: 1' -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36' -H 'accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' -H 'cache-control: no-cache' -H 'authority: meta.stackoverflow.com' -H 'cookie: prov=xxxxxxxxxxx; __qca=P0-xxxxxxx-xxxxxx; acct=t=xxxxxxxxxxxx; _ga=GA1.2.xxxxxxxx; _gid=GA1.2.xxxxxxx; _ga=GA1.3.xxxxxxx; _gid=xxxxxxxxx9' -H 'referer: https://meta.stackoverflow.com/' --compressed

答案 1 :(得分:4)

不幸的是,登录协议比这复杂得多,并且不是内置卷曲的方案。这不是curl的工作,而是一些脚本语言(如PHP或Python),虽然libcurl对管理http协议和cookie等有很大帮助。和libxml2将有助于解析登录CSRF密钥,该密钥隐藏在HTML中。并且他们可能需要一个referer标题,他们甚至可能会检查引用标题是真实的,而不是伪造的(idk,但它不会让我感到惊讶)。

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

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

这是PHP中的一个例子,使用libcurl和libxml2(使用PHP的DOMDocument作为libxml2的便利包装,并使用来自https://github.com/divinity76/hhb_.inc.php/blob/master/hhb_.inc.php的hhb_curl作为libcurl的便利包装,处理cookie,引用,libcurl错误处理(将无声的libcurl错误转换为异常,等等),最后,它会转储已登录的HTML,证明它已登录。(并且提供的电子邮件/密码是一个虚拟帐户,用于测试,它没有问题)受到损害,这显然发生在我在这里发布凭证。):

<?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 () );

有趣的是,默认情况下,libcurl在POST请求中使用multipart/form-data - 编码,但此站点(实际上是大多数站点)在POST请求中使用application/x-www-form-urlencoded - 编码。在这里,我使用PHP的http_build_query()以application/x-www-form-urlencoded格式编码POST数据 - 格式

答案 2 :(得分:3)

登录网址不是https://sustainability.stackexchange.com/ https://sustainability.stackexchange.com/users/login

,您推荐的链接说

curl -u username:password $URL

不是

curl $URL -u username:password

尝试

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

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

更新

Stack Exchange需要一个额外的登录密钥,称为fkey。如果您从浏览器中检查了登录表单,则可以看到名称为hidden的{​​{1}}输入字段,值为哈希值。需要识别会话并防止虚假登录尝试。

答案 3 :(得分:3)

如果您(使用Chrome)查看登录页面上的登录表单(右键单击,检查,查看html),您会发现该表单正在发布emailpassword字段https://sustainability.stackexchange.com/users/login

使用curl的方法是:

curl https://sustainability.stackexchange.com/users/login -d "email=test@test.com&password=monkey"

如果你仔细阅读返回的html,你会发现这是一个无效的登录。

问题是,如果您想在后续通话中使用已登录的会话,则需要存储您从网站获取的会话Cookie,以便进行后续通话。查看curl手册页,您可以看到-c <cookie_jar_file>选项。如果您使用文件名传递它,它应该保存登录呼叫中的cookie,您应该能够使用您已建立的会话进行后续呼叫,并且您应该开展业务。

编辑: 这里的其他答案和评论指出了这个答案中缺少的一些东西。获取并随后发布csrf密钥以及发布的正确MIME类型是必要的。它当然可以在命令行上执行此操作,但使用更完整的语言(根据接受的答案)会更容易。我确实发现这个问题有一个工具的建议,可能会用来删除使其工作所需的HTML / XML片段:https://superuser.com/questions/528709/command-line-css-selector-tool/528728