python - mvn - google cloud
¿Cómo se accede a un servicio autenticado de Google App Engine desde un cliente python(no web)? (5)
No estoy muy familiarizado con AppEngine, o las aplicaciones web de Googles, pero para un enfoque de fuerza bruta, podrías escribir un script con algo como mechanize ( http://wwwsearch.sourceforge.net/mechanize/ ) para simplemente recorrer el proceso de inicio de sesión antes que tú comienza a hacer el trabajo real del cliente.
Tengo una aplicación de Google App Engine - http://mylovelyapp.appspot.com/ Tiene una página - mylovelypage
Por el momento, la página solo hace self.response.out.write(''OK'')
Si ejecuto el siguiente Python en mi computadora:
import urllib2
f = urllib2.urlopen("http://mylovelyapp.appspot.com/mylovelypage")
s = f.read()
print s
f.close()
imprime "OK"
el problema es si agrego el login:required
para esta página en el yall de la aplicación
luego imprime el HTML de la página de inicio de sesión de Cuentas de Google
Probé métodos de autenticación "normales". p.ej
passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
auth_handler = urllib2.HTTPBasicAuthHandler()
auth_handler.add_password(None,
uri=''http://mylovelyapp.appspot.com/mylovelypage'',
user=''[email protected]'',
passwd=''billybobspasswd'')
opener = urllib2.build_opener(auth_handler)
urllib2.install_opener(opener)
Pero no hace ninguna diferencia: sigo recibiendo el HTML de la página de inicio de sesión.
Probé la API de autenticación ClientLogin de Google , pero no puedo hacer que funcione.
h = httplib2.Http()
auth_uri = ''https://www.google.com/accounts/ClientLogin''
headers = {''Content-Type'': ''application/x-www-form-urlencoded''}
myrequest = "Email=%s&Passwd=%s&service=ah&source=DALELANE-0.0" % ("[email protected]", "billybobspassword")
response, content = h.request(auth_uri, ''POST'', body=myrequest, headers=headers)
if response[''status''] == ''200'':
authtok = re.search(''Auth=(/S*)'', content).group(1)
headers = {}
headers[''Authorization''] = ''GoogleLogin auth=%s'' % authtok.strip()
headers[''Content-Length''] = ''0''
response, content = h.request("http://mylovelyapp.appspot.com/mylovelypage",
''POST'',
body="",
headers=headers)
while response[''status''] == "302":
response, content = h.request(response[''location''], ''POST'', body="", headers=headers)
print content
Parece que puedo obtener algunos tokens correctamente, pero intento usarlos en el encabezado cuando llamo ''mylovelypage''; solo me devuelven el HTML de la página de inicio de sesión. :-(
¿Alguien puede ayudar, por favor?
¿Podría usar la biblioteca del cliente GData para hacer este tipo de cosas? Según lo que he leído, creo que debería poder acceder a las aplicaciones de App Engine, pero no he tenido más éxito en conseguir que la autenticación funcione para App Engine allí tampoco.
Cualquier sugerencia para muestras, artículos o incluso solo palabras clave que debería buscar para comenzar, sería muy apreciada.
¡Gracias!
No soy un experto en python ni un experto en motores de aplicaciones. Pero, ¿probaste seguir el ejemplo de aplicación en http://code.google.com/appengine/docs/gettingstarted/usingusers.html . Creé uno en http://quizengine.appspot.com , parecía funcionar bien con la autenticación de Google y todo. Solo una sugerencia, pero mira la guía de introducción. Tómatelo con calma si la sugerencia parece ingenua. :) Gracias.
appcfg.py, la herramienta que carga datos en App Engine tiene que hacer exactamente esto para autenticarse con el servidor de App Engine. La funcionalidad relevante se resume en appengine_rpc.py. En pocas palabras, la solución es:
- Use la API Google ClientLogin para obtener un token de autenticación. appengine_rpc.py hace esto en _GetAuthToken
- Envía el token de autenticación a una URL especial en tu aplicación de App Engine. Esa página luego devuelve una cookie y un redireccionamiento 302. Ignore la redirección y almacene la cookie. appcfg.py hace esto en _GetAuthCookie
- Use la cookie devuelta en todas las solicitudes futuras.
También puede consultar _Authenticate , para ver cómo appcfg maneja los diversos códigos de retorno de ClientLogin y _GetOpener , para ver cómo appcfg crea un OpenerDirector urllib2 que no sigue los redireccionamientos HTTP. O podría, de hecho, simplemente usar las clases AbstractRpcServer y HttpRpcServer al por mayor, ya que hacen prácticamente todo lo que necesita.
gracias a Arachnid por la respuesta, funcionó como se sugirió
¡Aquí hay una copia simplificada del código, en caso de que sea útil para la siguiente persona para intentarlo!
import os
import urllib
import urllib2
import cookielib
users_email_address = "[email protected]"
users_password = "billybobspassword"
target_authenticated_google_app_engine_uri = ''http://mylovelyapp.appspot.com/mylovelypage''
my_app_name = "yay-1.0"
# we use a cookie to authenticate with Google App Engine
# by registering a cookie handler here, this will automatically store the
# cookie returned when we use urllib2 to open http://currentcost.appspot.com/_ah/login
cookiejar = cookielib.LWPCookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookiejar))
urllib2.install_opener(opener)
#
# get an AuthToken from Google accounts
#
auth_uri = ''https://www.google.com/accounts/ClientLogin''
authreq_data = urllib.urlencode({ "Email": users_email_address,
"Passwd": users_password,
"service": "ah",
"source": my_app_name,
"accountType": "HOSTED_OR_GOOGLE" })
auth_req = urllib2.Request(auth_uri, data=authreq_data)
auth_resp = urllib2.urlopen(auth_req)
auth_resp_body = auth_resp.read()
# auth response includes several fields - we''re interested in
# the bit after Auth=
auth_resp_dict = dict(x.split("=")
for x in auth_resp_body.split("/n") if x)
authtoken = auth_resp_dict["Auth"]
#
# get a cookie
#
# the call to request a cookie will also automatically redirect us to the page
# that we want to go to
# the cookie jar will automatically provide the cookie when we reach the
# redirected location
# this is where I actually want to go to
serv_uri = target_authenticated_google_app_engine_uri
serv_args = {}
serv_args[''continue''] = serv_uri
serv_args[''auth''] = authtoken
full_serv_uri = "http://mylovelyapp.appspot.com/_ah/login?%s" % (urllib.urlencode(serv_args))
serv_req = urllib2.Request(full_serv_uri)
serv_resp = urllib2.urlopen(serv_req)
serv_resp_body = serv_resp.read()
# serv_resp_body should contain the contents of the
# target_authenticated_google_app_engine_uri page - as we will have been
# redirected to that page automatically
#
# to prove this, I''m just gonna print it out
print serv_resp_body
para aquellos que no pueden hacer que ClientLogin funcione, prueba la compatibilidad con OAuth del motor de aplicaciones.