2010-05-21 3 views
14

Je travaille sur un projet et je souhaite me connecter à Stack Overflow via cURL. J'utilise Google comme fournisseur openID, ce qui signifie que je dois d'abord me connecter à Google via son API.Connexion au débordement de pile avec cURL

Voici le code que j'ai jusqu'à présent:

#!/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; 

À ce stade, je reçois une page de Google me disant que Stack Overflow veut des informations et je dois connecter Selon this page, la --header ... $Auth partie. devrait compter comme un login et me rediriger vers Stack Overflow.

Voici la forme que je reçois quand je lance ce script:

<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> 

Lorsque je tente la réponse ci-dessous je reçois l'erreur suivante:

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

ici est la sortie de 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> 
+0

Avez-vous essayé de changer le UserAgent de curl? – ZyX

+1

ZyX - Pour quelle raison aurais-je le changement de l'UA? À ce stade, il n'est même pas en train de se connecter et encore moins de me donner un code spécifique à UA. –

+1

il pourrait avoir une fonction de sécurité de ne pas vous permettre de vous connecter avec un agent utilisateur php ... –

Répondre

9

Le service de connexion Google est spécifique au service que vous utilisez (Go Google Docs contre Google Analytics vs Google Maps, etc.). L'ode de service que vous avez spécifié (lh2) est spécifique à Google Picasa.

Malheureusement, il ne semble pas être un code équivalent pour OpenId (au moins, pas que je pouvais trouver!)

La page que vous revenez de Google devrait contenir un formulaire de connexion. Si vous regardez cela, il devrait être possible de construire une invocation curl pour vous connecter; cela devrait ensuite vous rediriger vers SO (ou n'importe quelle page openID à laquelle vous voulez vous connecter)

Il s'avère que cela est un peu délicat, car vous devez analyser certains des champs de formulaire. pour les renvoyer à Google, et parce que Google ne renvoie pas une redirection HTTP directe, mais un document HTML avec une balise <meta http-equiv="redirect" ...>. Et bien sûr, vous devez activer les cookies. Mais tout cela est possible dans un script utilisant CURL - les œuvres suivantes pour moi:

#!/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 - "[email protected]" <<EOF 
     @[email protected]; 
     \$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" 

(Notez que je semble avoir une version légèrement différente de boucle de vous, donc je devais changer les -w des options légèrement; Je suppose que ma version fonctionnera pour vous mais vous devrez peut-être la modifier.)

+0

J'ai trouvé le code de service dans le formulaire et j'ai changé mon code ci-dessus pour le faire correspondre ("lso") . Cependant, cela ne se connecte toujours pas. –

+0

Ce que je voulais dire, c'est soumettre le formulaire lui-même en utilisant curl ... si vous postez le contenu de ce formulaire (juste le contenu de la balise FORM), il pourrait être possible de fournir d'autres indices. .. – psmears

+0

@psmears: J'ai posté le formulaire. –

Questions connexes