Jak uzyskać dostęp do uwierzytelnionej usługi Google App Engine z (nie-internetowego) klienta Pythona?

Mam aplikację Google App Engine - http://mylovelyapp.appspot.com/ Ma stronę-mylovelypage

Na razie strona robi self.response.out.write('OK')

Jeśli uruchamiam następujący Python na moim komputerze:

import urllib2
f = urllib2.urlopen("http://mylovelyapp.appspot.com/mylovelypage")
s = f.read()
print s
f.close()

Drukuje " OK "

Problem polega na tym, że jeśli dodam login:required do tej strony w aplikacji yaml

Następnie wyświetla HTML strony logowania kont Google

Próbowałem "normalnych" metod uwierzytelniania. np.

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)

Ale to sprawia, że nie różnica - nadal odzyskuję HTML strony logowania.

Próbowałem Google ClientLogin auth API, ale nie mogę go uruchomić.

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

Wydaje się, że jestem w stanie poprawnie uzyskać jakiś token, ale próby użycia go w nagłówku, gdy wywołuję "mylovelypage", nadal po prostu zwracają mi HTML strony logowania. :-(

Czy ktoś może pomóc?

Czy mogę użyć biblioteki klienta GData do tego typu rzeczy? Od to, co przeczytałem, myślę, że powinno być w stanie dostęp do aplikacji App Engine, ale nie odniosłem większych sukcesów w uzyskaniu uwierzytelniania działającego tam na silniku aplikacji

Wszelkie wskazówki do próbek, artykułów, a nawet tylko słowa kluczowe powinienem być szukanie mnie na początek, byłoby bardzo mile widziane.

Dzięki!
Author: Charles, 2008-09-19

5 answers

Appcfg.py narzędzie, które przesyła dane do silnika aplikacji, musi dokładnie to zrobić, aby uwierzytelnić się za pomocą serwera silnika aplikacji. Odpowiednia funkcjonalność jest wyodrębniona na appengine_rpc.py. w skrócie rozwiązaniem jest:

  1. Użyj Google ClientLogin API , aby uzyskać token uwierzytelniania. appengine_rpc.py czy to w _getauthtoken
  2. Wyślij token auth na specjalny adres URL w aplikacji App Engine. Ta strona następnie zwraca plik cookie i 302 przekierowanie. Zignoruj przekierowanie i zapisz plik cookie. appcfg.py czy to w _getauthookie
  3. Użyj zwracanego pliku cookie we wszystkich przyszłych żądaniach.

Możesz również spojrzeć na _Authenticate, aby zobaczyć, jak appcfg obsługuje różne kody zwrotne z ClientLogin, i _GetOpener, aby zobaczyć, jak appcfg tworzy OpenerDirector urllib2, który nie podąża za przekierowaniami HTTP. Możesz też użyć klas AbstractRpcServer i HttpRpcServer hurtowo, ponieważ robią prawie wszystko, czego potrzebujesz.

 39
Author: Nick Johnson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-14 09:21:52

Dzięki Arachnid za odpowiedź-zadziałało zgodnie z sugestią

Tutaj jest uproszczona Kopia kodu, na wypadek, gdyby była pomocna dla następnej osoby, aby spróbować!

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
 34
Author: dalelane,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-19 16:39:30

Dla tych, którzy nie mogą uruchomić ClientLogin, spróbuj app engine OAuth support .

 1
Author: ryan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-27 06:59:18

Nie jestem zbyt zaznajomiony z AppEngine, lub Googles Web API, ale dla podejścia brute force można napisać skrypt z czymś takim jak mechanize ( http://wwwsearch.sourceforge.net/mechanize/), aby po prostu przejść przez proces logowania, zanim zaczniesz wykonywać prawdziwą pracę Klienta.

 0
Author: Sean O Donnell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-19 14:16:24

Nie jestem ekspertem w Pythonie ani w App engine. Ale czy próbowałeś podążać za przykładowym appl w http://code.google.com/appengine/docs/gettingstarted/usingusers.html . stworzyłem w http://quizengine.appspot.com , wydawało się, że działa dobrze z uwierzytelnianiem Google i w ogóle. To tylko sugestia, ale zajrzyj do przewodnika Pierwsze kroki. Spokojnie, jeśli sugestia brzmi naiwnie. :) Dzięki.

 -1
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-19 14:16:12