统一gdata和较新的Google API之间的OAuth处理 [英] Unifying OAuth handling between gdata and newer Google APIs
问题描述
我正在使用 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屋!