Google calendar api 统一gdata和更新的Google API之间的OAuth处理

Google calendar api 统一gdata和更新的Google API之间的OAuth处理,google-calendar-api,gdata-api,google-contacts-api,google-api-python-client,google-shared-contacts,Google Calendar Api,Gdata Api,Google Contacts Api,Google Api Python Client,Google Shared Contacts,我正在用Python处理和。前者是GDataAPI,后者是Google API。。。API,所以虽然客户机可用,但它们都由单独的客户机覆盖——以下是,和 我在与这些客户机合作时遇到的问题是,它们都有自己处理OAuth2的方法。GData库提供了GData.gauth.token\u to_blob(auth\u token)和GData.gauth.token\u from_blob(auth\u token)方法来将auth token转换为字符串或从字符串转换为存储在数据库中,而google

我正在用Python处理和。前者是GDataAPI,后者是Google API。。。API,所以虽然客户机可用,但它们都由单独的客户机覆盖——以下是,和

我在与这些客户机合作时遇到的问题是,它们都有自己处理OAuth2的方法。GData库提供了
GData.gauth.token\u to_blob(auth\u token)
GData.gauth.token\u from_blob(auth\u token)
方法来将auth token转换为字符串或从字符串转换为存储在数据库中,而googleapi库提供了(我为之编写的平台)来存储OAuth凭证


我看不到一种清晰的方法来存储两个API都可以访问的单一内容(无论是访问令牌还是凭据),但我真的不希望用户必须进行两次身份验证。除了抛弃Google的客户端库和编写直接的HTTP调用之外,还有什么方法可以实现这一点吗?

看来您需要改变自己的方式,重写GDataAPI,以便使用来自客户端的令牌


但是,即使您能够让GData按照您想要的方式运行,也要记住标记是为特定的范围提供的,因此您需要强制gdataapi使用googlecalendarapi,反之亦然。不过,我不知道这是否可以做到。

我能够完成以下工作。它使用
oauth2decorator
来完成繁重的工作,然后使用一个小的助手类
tokenfromOAuth2cles
将这些相同的凭证应用到gdata客户端

我应该说我不是gdata专家——也许有更好的方法可以做到这一点——但我还没有完全测试过

import webapp2
import httplib2
from oauth2client.appengine import oauth2decorator_from_clientsecrets
from apiclient.discovery import build

import gdata.contacts.client

decorator = oauth2decorator_from_clientsecrets(
  "client_secrets.json",
  scope=["https://www.google.com/m8/feeds", "https://www.googleapis.com/auth/calendar.readonly"]
)


# Helper class to add headers to gdata
class TokenFromOAuth2Creds:
  def __init__(self, creds):
    self.creds = creds
  def modify_request(self, req):
    if self.creds.access_token_expired or not self.creds.access_token:
      self.creds.refresh(httplib2.Http())
    self.creds.apply(req.headers)


class MainHandler(webapp2.RequestHandler):
  @decorator.oauth_required
  def get(self):
    # This object is all we need for google-api-python-client access
    http = decorator.http()

    # Create a gdata client
    gd_client = gdata.contacts.client.ContactsClient(source='<var>YOUR_APPLICATION_NAME</var>')

    # And tell it to use the same credentials
    gd_client.auth_token = TokenFromOAuth2Creds(decorator.get_credentials())

    # Use Contacts API with gdata library
    feed = gd_client.GetContacts()
    for i, entry in enumerate(feed.entry):
      self.response.write('\n%s %s' % (i+1, entry.name.full_name.text if entry.name else ''))

    # Use Calendar API with google-api-python-client
    service = build("calendar", "v3")
    result = service.calendarList().list().execute(http=http)
    self.response.write(repr(result))

app = webapp2.WSGIApplication([
  ("/", MainHandler),
  (decorator.callback_path, decorator.callback_handler()),
], debug=True)
使用gdata的另一种方法是直接使用
http
对象(由
decorator.http()
返回)-此对象将自动为您添加正确的授权头-这可用于向任一API发出请求,但您需要亲自处理请求和解析XML/JSON:

class MainHandler(webapp2.RequestHandler):
  @decorator.oauth_required
  def get(self):
    http = decorator.http()

    self.response.write(http.request('https://www.google.com/m8/feeds/contacts/default/full')[1])    
    self.response.write(http.request('https://www.googleapis.com/calendar/v3/users/me/calendarList')[1])
httplib2的文档:

谢谢您的回答@aeijdenberg。当您说“使用gdata的替代方法”时,您的意思是在不使用gdata库的情况下访问HTTP端点,并使用其他方法来处理提要吗?我可能会这样做,但我不确定如何按照您的建议直接使用
http
对象。我在库文档中看到的代码只是将对象传递到库方法中;它不是直接调用的。在上面添加了节。
class MainHandler(webapp2.RequestHandler):
  @decorator.oauth_required
  def get(self):
    http = decorator.http()

    self.response.write(http.request('https://www.google.com/m8/feeds/contacts/default/full')[1])    
    self.response.write(http.request('https://www.googleapis.com/calendar/v3/users/me/calendarList')[1])