2014年3月18日 星期二

[gae]用程式登入 google app engine 建立的服務

這裡用到的是 google 已說要廢棄的 ClientLogin。

這是我很久以前使用的方法,雖然 google 說已經廢棄,但現在還是可以使用。

 

要能夠被 GAE 認為是登入過的使用者,主要就是在 cookie 裡面,看到 auth 這個 token。
而要拿到 auth 這個 token 的值,就得從 google account authorization 拿到。
因此,第一步是知道 google account authorization 的網址:

https://www.google.com/accounts/ClientLogin

post request 裡面要用 application/x-www-form-urlencoded 包含幾個必要內容:

  • Email:登入者的帳號。
  • Passwd:登入者的密碼。
  • service:值為 ah。我忘記為什麼是 ah 了。對於登入 GAE ,填 ah 是可以的。
  • source:自己的 GAE 服務的名字。
  • accountType:"HOSTED_OR_GOOGLE",原因請參照文末的參考。

在填入以上必要資訊之後,傳送 post request 給 clientlogin 的 service,可以在 response 裡面拿到 Auth 的值。這就是參考裡面流程的第7步。

接下來,是跟 GAE 的事。要讓 GAE 知道你拿到 auth 的 token 並且幫忙導至想要的位置,要將 request 送去以下的網址:

http://你的GAE服務網址/_ah/login?continue=你想導去的網址&auth=拿到的token值

這樣,GAE 服務那裡的程式,從 users.get_current_user() 就會拿到值,便可以當做 user 已經 login 了。

在這兩個 request 裡,會用到 cookie。在 python 中,要使用有 cookie 功能的 http client,要使用 urllib2 與 cookielib 配合使用。範例如下:

cookiejar = cookielib.LWPCookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookiejar))
urllib2.install_opener(opener)

如此,urllib2.urlopen 就會有 cookie 功能,才能夠以上兩個 post request 正常工作。完整的 python 範例如下:

import urllib
import urllib2
import cookielib

def passauth(login_address, login_pass, login_app, login_app_address):

  url = login_app_address
  users_email_address=login_address
  users_password=login_pass
  target_authenticated_google_app_engine_uri= 'http://%s' % login_app_address
  my_app_name = login_app
  cookiejar = cookielib.LWPCookieJar()
  opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookiejar))
  urllib2.install_opener(opener)

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

  print 'auth_resp_body', auth_resp_body
  auth_resp_dict = dict(x.split("=")
                        for x in auth_resp_body.split("\n") if x)
  authtoken = auth_resp_dict["Auth"]
  serv_uri = target_authenticated_google_app_engine_uri
  serv_args = {}
  serv_args['continue'] = serv_uri
  serv_args['auth']     = authtoken


  full_serv_uri = "http://%s/_ah/login?%s" % (url,urllib.urlencode(serv_args))

  return full_serv_uri

full_serv_uri = passauth('xxxxx@gmail.com','yyyyy','zzzzz','zzzzz.appspot.com')
print 'full_serv_uri',full_serv_uri
serv_req = urllib2.Request(full_serv_uri)
serv_resp = urllib2.urlopen(serv_req)
serv_resp_body = serv_resp.read()
print 'serv_resp_body', serv_resp_body

 

參考:

https://developers.google.com/accounts/docs/AuthForInstalledApps?hl=zh-tw

沒有留言:

張貼留言