统一gdata和较新的Google API之间的OAuth处理 [英] Unifying OAuth handling between gdata and newer Google APIs

本文介绍了统一gdata和较新的Google API之间的OAuth处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Google联系人API Google Calendar API .前者是GData API,后者是Google API ... API,因此尽管有可用的客户端,但每个客户端都由单独的客户端覆盖-这是 Google API .

I'm working with the Google Contacts API and Google Calendar API in Python. The former is a GData API and the latter is a Google API... API, so while clients are available, they're each covered by separate clients -- here's GData, and Google API.

我正在与这些客户端打交道的问题是,它们都有自己的OAuth2处理方式. GData库提供了gdata.gauth.token_to_blob(auth_token)gdata.gauth.token_from_blob(auth_token)方法,以将身份验证令牌与字符串进行相互转换以存储在数据库中,而google-api库则提供了

The problem I'm running into working with these clients is that they both have their own way of dealing with OAuth2. The GData library provides gdata.gauth.token_to_blob(auth_token) and gdata.gauth.token_from_blob(auth_token) methods to translate auth tokens to/from strings to store in a database, while the google-api library provides a method on App Engine (the platform I'm writing for) to store the OAuth credentials.

我看不到一种清晰的方法来存储可同时用于两个API的单个事物(无论是访问令牌还是凭证),但是我真的不希望用户必须进行身份验证两次.除了放弃Google的客户端库并编写直接的HTTP调用之外,还有什么方法可以实现?

I don't see a clear way to store a single thing (whether it be an access token or credentials) accessible to both APIs, but I really don't want users to have to authenticate twice. Is there a way to accomplish this, short of ditching Google's client libraries and writing straight HTTP calls?

推荐答案

我能够完成以下工作.它使用oauth2decorator进行繁重的工作,然后使用一个小的帮助程序类TokenFromOAuth2Creds将该相同的凭据应用于gdata客户端.

I was able to get the following working. It uses the oauth2decorator to do the heavy lifting, then it uses a small helper class TokenFromOAuth2Creds to apply those same credentials to the gdata client.

我应该以我不是gdata专家的身份开头-并且可能会有更好的方法-而且我还没有进行全面的测试.

I should preface that I'm no gdata expert - and there may be better ways of doing this - and I haven't thoroughly tested.

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)

请注意,如果您不使用装饰器,并且已通过其他方式获得了凭据对象,则可以通过以下方式创建相同的预授权http对象:

Note, if you're not using the decorator, and have gotten your credentials object by other means, you can create the same pre-authorized http object by:

http = credentials.authorize(httplib2.Http())

使用gdata的另一种方法是直接使用http对象(由decorator.http()返回)-该对象将自动为您添加正确的授权标头-可用于向​​任一API发出请求,但您可以将需要自行处理请求并自行解析XML/JSON:

An alternative to using gdata is to use the http object (returned by decorator.http()) directly - this object will automatically add the right authorization headers for you - this can be used to make requests to either API, but you'll need to handle crafting the request and parsing the XML/JSON yourself:

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的文档: http://httplib2.googlecode.com/hg/doc/html/libhttplib2.html#http-objects

Docs for httplib2: http://httplib2.googlecode.com/hg/doc/html/libhttplib2.html#http-objects

这篇关于统一gdata和较新的Google API之间的OAuth处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆