14

私はプロジェクトに取り組んでおり、cURL 経由で Stack Overflow にログインしたいと考えています。

私は Google を openID プロバイダーとして使用しています。つまり、最初に API を介して Google にログインする必要があります。

これが私がこれまでに持っているコードです:

#!/bin/sh
. ./params.sh #the script with $username and $password
curl --silent https://www.google.com/accounts/ClientLogin \
-d Email=$username -d Passwd=$password \
-d accountType=GOOGLE \
-d source=localhost-test-1 \
-d service=lso \
-o tokens
. ./tokens
echo $Auth; #$Auth is correct here - I did not get a BadAuth error.

endpoint="https://www.google.com/accounts/o8/id";

curl http://stackoverflow.com/users/authenticate \
    -d "openid_identifier=$endpoint" \
    -w %{redirect_url}> ./google_url
google_url=$(cat ./google_url);
echo $google_url;
echo;
echo;
echo;
curl -L --silent --header "Authorization: GoogleLogin auth=$Auth" $google_url;

この時点で、Google からページが表示され、スタック オーバーフローが情報を求めているのでログインする必要があることがわかります。このページによると、その--header ... $Auth部分はログインとしてカウントされ、スタック オーバーフローにリダイレクトされます。

このスクリプトを実行したときに得られるフォームは次のとおりです。

<form id="gaia_universallogin"
      action="https://www.google.com/accounts/ServiceLoginAuth?service=lso" method="post">
  <input type="hidden" name="continue" id="continue"
           value="https://www.google.com/accounts/o8/ud?st=SOME_KEY" />
  <input type="hidden" name="service" id="service"
           value="lso" />
  <input type="hidden" name="dsh" id="dsh"
           value="SOME_NEG_NUMBER" />
</form>

以下の答えを試すと、次のエラーが表示されます。

    Can't call method "attr" on an undefined value at - line 8.
    curl: (3) <url> malformed
--></style>

ここからの出力ですgoogle2.html

<form id="gaia_loginform"      
        action="https://www.google.com/accounts/ServiceLoginAuth?service=lso" method="post"                >
  <input type="hidden" name="continue" id="continue"            value="https://www.google.com/accounts/o8/ud?st=RNADOM" />
  <input type="hidden" name="service" id="service"            value="lso" />
  <input type="hidden" name="dsh" id="dsh"            value="NEG_NUMEBER" />
  <input type="hidden"              name="GALX"             value="ABCD" />
  <input type="text" name="Email"  id="Email" />
  <input type="password"   name="Passwd" id="Passwd" > 
  <input type="checkbox" name="PersistentCookie" id="PersistentCookie"    value="yes"
  <input type="hidden" name='rmShown' value="1" />
  <input type="submit" class="gaia le button" name="signIn" id="signIn"                 />
<input type="hidden" name="asts"    >
</form>
4

1 に答える 1

9

Google ログイン サービスは、使用している特定のサービスに固有のものです (Google ドキュメント、Google アナリティクス、Google マップなど)。指定したサービス コード (lh2) は、Google Picasa に固有のものです。

残念ながら、OpenId に相当するコードはないようです (少なくとも、私が見つけたものではありません!)。

Google から返されたページには、ログイン フォームが含まれている必要があります。それを見ると、ログインするためのカール呼び出しを作成できるはずです。これにより、ログインした SO (またはログインしたい openID ページ) にリダイレクトされます。

フォーム フィールドの一部を解析して Google に送信する必要があり、Google は HTTP リダイレクトを直接送信するのではなく、<meta http-equiv="redirect" ...>タグ付きの HTML ドキュメントを送信するため、これを行うのは少し難しいことがわかりました。 . もちろん、Cookie を有効にする必要があります。しかし、これはcurlを使用したスクリプトですべて可能です-私にとっては次のように機能します:

#!/bin/bash

# Utility function for parsing values out of an HTML form
get_value()
{
    local tagtype="$1" attrname="$2" attrvalue="$3" getattr="$4"
    perl -MHTML::TreeBuilder - "$@" <<EOF
         @args=@ARGV;
         \$h=HTML::TreeBuilder->new;
         \$h->parse_file("$htmlfile");
         while (\$#args > 0) {
             \$h=\$h->look_down(_tag => shift @args,
                                shift @args => shift @args);
         }
         print \$h->attr(shift @args);
EOF
}

# Empty the cookie jar
cj="cookiejar"
rm -f "$cj"

# Attempt to log in to SO. This will redirect to a google URL.
endpoint="https://www.google.com/accounts/o8/id"

google_url=`curl -L -s -S http://stackoverflow.com/users/authenticate \
    -d "openid_identifier=$endpoint" \
    -o /dev/null -b "$cj" -c "$cj" \
    -w %{url_effective}`
echo $google_url
echo
echo

# Retrieve the form from Google
htmlfile=googleform.html
curl -L -s -S -o "$htmlfile" -b "$cj" -c "$cj" "$google_url"

# Parse out the form fields
form_url=`get_value form id gaia_loginform action`

fdsh=`get_value form id gaia_loginform input name dsh value`
fcontinue=`get_value form id gaia_loginform input name continue value`
fservice=`get_value form id gaia_loginform input name service value`
fGALX=`get_value form id gaia_loginform input name GALX value`
frmShown=`get_value form id gaia_loginform input name rmShown value`
fsignIn=`get_value form id gaia_loginform input name signIn value`

fEmail='INSERT LOGIN EMAIL HERE'
fPasswd='INSERT PASSWORD HERE'

# Submit the login form
htmlfile=google2.html
curl -L -s -S -o "$htmlfile" -b "$cj" -c "$cj" --data-urlencode dsh="$fdsh" \
  --data-urlencode continue="$fcontinue" \
  --data-urlencode service="$fservice" \
  --data-urlencode GALX="$fGALX" \
  --data-urlencode Email="$fEmail" \
  --data-urlencode Passwd="$fPasswd" \
  --data-urlencode rmShown="$frmShown" \
  --data-urlencode signIn="$fsignIn" \
  "$form_url"

# Interpret the redirect
redirect=`get_value meta http-equiv refresh content | sed "s/^.*'\(.*\)'.*$/\1/"`

# Follow it
htmlfile=google3.html
curl -L -s -S -o "$htmlfile" -b "$cj" -c "$cj" "$redirect"

(私はあなたとは少し異なるバージョンのcurlを持っているように見えるので、-wオプションを少し変更しなければならなかったことに注意してください。私のバージョンはあなたのために働くと思いますが、微調整する必要があるかもしれません。)

于 2010-05-29T18:20:54.170 に答える