问题
I really need some help here, I've been at this for almost 2 weeks.
What I'm trying to do is use Google's provisioning API inside of GAE (Google App Engine) using oAuth2. I know there are a few of examples using oAuth1 to accomplish this. My understanding though is that oAuth1 is now deprecated and we must used oAuth2, please correct me if I am wrong.
I've scoured the internet and the only example I could find to work from is this:
http://gdata-samples.googlecode.com/svn-history/r232/trunk/gdata/youtube-oauth2-app-engine/main.py
Other examples I've found use oAuth 1, or they are not designed to be used with App Engine.
I've taken the code from the example above and attempted to modify it to work with the groups provisioning API, here is my code:
import os
from gdata.alt import appengine
from gdata.service import RequestError
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp import util
from oauth2client.appengine import OAuth2Decorator
import gdata.auth
import gdata.apps.groups.client
import gdata.client
import httplib2
API_VERSION = '2.0'
BASE_URL = '/a/feeds/group/%s' % API_VERSION
# HACK to use the Python GData client library with OAuth 2 tokens.
# We use the methods that deal with AuthSub tokens.
gdata.auth.AUTHSUB_AUTH_LABEL = "OAuth "
class MainHandler(webapp.RequestHandler):
# The client_id and client_secret are copied from the API Access tab on
# the Google APIs Console <http://code.google.com/apis/console>
oauth2_decorator = OAuth2Decorator(
client_id="myClientID.apps.googleusercontent.com",
client_secret="myClientSecret",
scope="https://apps-apis.google.com/a/feeds/groups/")
# This decorator ensures that whenever this page is served, we have a valid
# OAuth 2 token for the user.
@oauth2_decorator.oauth_required
def handle_exception(self, exception, debug_mode):
"""Handle OAuth 2 token expirations by forcing a refresh.
For newer Google APIs, refreshes are handled automatically by the client
library, but for GData APIs, we need to explicitly force this behavior.
"""
if (isinstance(exception, RequestError) and
exception.args[0]["status"] == 401):
body = exception.args[0]["body"]
if "Token invalid - Invalid AuthSub token." in body:
self.oauth2_decorator.credentials._refresh(httplib2.Http().request)
self.redirect(self.request.url)
return
webapp.RequestHandler.handle_exception(self, exception, debug_mode)
# This decorator ensures that whenever this page is served, we have a valid
# OAuth 2 token for the user.
@oauth2_decorator.oauth_required
def get(self):
self.domain='testdomain123456.mygbiz.com'
self.baseuri = '%s/%s' % (BASE_URL, 'testdomain123456.mygbiz.com')
self.token = self.oauth2_decorator.credentials.access_token
self.client = gdata.apps.groups.client.GroupsProvisioningClient(
domain=self.domain, auth_token=self.token)
self.client.SetAuthSubToken(self.token)
params = dict(
logout_url=users.create_logout_url(self.request.uri),
memberFeed = self.client.RetrieveAllMembers('test')
)
path = os.path.join(os.path.dirname(__file__), 'templates', 'index.html')
self.response.out.write(template.render(path, params))
def main():
application = webapp.WSGIApplication([('/', MainHandler)], debug=True)
util.run_wsgi_app(application)
if __name__ == '__main__':
main()
I deployed this to http://appplat4.appspot.com, and as you can see it returns a 500 server error. I have all of the necessary libraries in the same directory as app.yaml
and I have my google api set up for the domain.
Screenshot:
I've been trying everything I can to provision groups from within GAE with no success. Please help if you can, any amount of input is appreciated.
回答1:
This doesn't address app engine but it is a command line example using a gdata client with oauth 2:
import sys
import os
import webbrowser
import gdata.gauth
import oauth2client.client
import oauth2client.file
import oauth2client.tools
import gdata.gauth
import gdata.client
import gdata.apps.groups.client
APICONSOLE = 'https://code.google.com/apis/console'
SCOPES = 'https://apps-apis.google.com/a/feeds/groups/'
OAUTH2FILENAME = 'credentials.oauth2'
OAUTH2JSONFILE = 'client_secrets.json'
OAUTH2USERAGENT = 'GROUPS'
MISSING_OAUTHJSONFILE_MESSAGE = """
You must create or download a client secrets json file (%s)
from the Google APIs console <https://code.google.com/apis/console>.
Attemping to open page with your browser ...
""" % os.path.join(os.path.dirname(__file__), OAUTH2JSONFILE)
# populate with approprate values
DOMAIN = 'your-domain'
GROUP_ID = 'agroup@your.domain'
if not os.path.isfile(OAUTH2JSONFILE):
message = MISSING_OAUTHJSONFILE_MESSAGE
print message
try:
webbrowser.open(str(APICONSOLE))
except Exception, e:
print "Error opening web page"
sys.exit(1)
message = 'When %s is created/downloaded press Enter to continue ... ' %(OAUTH2JSONFILE)
raw_input(message)
oauth2_flow = oauth2client.client.flow_from_clientsecrets(OAUTH2JSONFILE,
scope=SCOPES,message=MISSING_OAUTHJSONFILE_MESSAGE)
storage = oauth2client.file.Storage(OAUTH2FILENAME)
oauth2_credentials = storage.get()
if oauth2_credentials is None or oauth2_credentials.invalid:
oauth2_credentials = oauth2client.tools.run(oauth2_flow, storage)
oauth2_token = gdata.gauth.OAuth2Token(
client_id=oauth2_credentials.client_id,
client_secret=oauth2_credentials.client_secret,
scope=SCOPES,
user_agent=OAUTH2USERAGENT,
access_token=oauth2_credentials.access_token,
refresh_token=oauth2_credentials.refresh_token)
# authorize client
groups_client = oauth2_token.authorize(
gdata.apps.groups.client.GroupsProvisioningClient(domain=DOMAIN))
print 'Authorized domain %s . . .\n' %(DOMAIN)
group_entry = groups_client.RetrieveGroup(group_id=GROUP_ID)
print group_entry.group_id
print group_entry.group_name
print group_entry.description
print group_entry.email_permission
sys.exit(0)
来源:https://stackoverflow.com/questions/13942439/google-app-engine-and-group-provisioning