在python中的GAE上使用OAuth2

在python中的GAE上使用OAuth2,python,google-app-engine,Python,Google App Engine,我正在尝试创建一个GAE应用程序,其中用户可以访问appspot域,使用OAuth2获得授权(或不授权),然后使用gdata.spreadsheet.service自动修改其中一个Google电子表格。我使用SignedJwtAssertionCredentials实现了这一点,但在这种情况下,用户必须明确允许从应用程序进行编辑;我试图跳过这一步,让应用程序使用OAuth2从用户自己的帐户修改用户的电子表格 谷歌提供的文档称,装饰师是实现这一点的最简单的方法,可以这样做: from apicli

我正在尝试创建一个GAE应用程序,其中用户可以访问appspot域,使用OAuth2获得授权(或不授权),然后使用
gdata.spreadsheet.service
自动修改其中一个Google电子表格。我使用
SignedJwtAssertionCredentials
实现了这一点,但在这种情况下,用户必须明确允许从应用程序进行编辑;我试图跳过这一步,让应用程序使用OAuth2从用户自己的帐户修改用户的电子表格

谷歌提供的文档称,装饰师是实现这一点的最简单的方法,可以这样做:

from apiclient.discovery import build
from google.appengine.ext import webapp
from oauth2client.appengine import OAuth2Decorator

decorator = OAuth2Decorator(
  client_id='your_client_id',
  client_secret='your_client_secret',
  scope='https://www.googleapis.com/auth/calendar')

service = build('calendar', 'v3')

...

  @decorator.oauth_required
  def get(self):
    # Get the authorized Http object created by the decorator.
    http = decorator.http()
    # Call the service using the authorized Http object.
    request = service.events().list(calendarId='primary')
    response = request.execute(http=http)

但是我不知道如何使用这个
服务
对象来完成电子表格修改的目标。关于如何使用
服务
对象的任何一般提示或特定提示都会有所帮助。

在提供的示例中,您正在使用Google calendar API构建日历服务,而Google calendar API不是基于GData的API。对于基于GData的API,您必须使用
GData.gauth

请注意,
gdata.spreadsheet.service
将无法与
gdata.gauth
一起使用,因为它只支持不推荐的客户端登录(请查看[1]中提供的
spreadsheets服务
构造函数)。您应该改用
gdata.spreadsheets.client

完整的
电子表格客户端
文档可从[2]获取。您可以考虑将工作表添加到电子表格中的示例:

import webapp2
import cgi
import atom.data
import gdata.data
import gdata.spreadsheets.client

from oauth2client.client import OAuth2WebServerFlow

SCOPE = 'https://spreadsheets.google.com/feeds'

flow = OAuth2WebServerFlow(
  client_id='your_client_id',
  client_secret='your_client_secret',
  scope=SCOPE,
  redirect_uri='https://your_app.appspot.com/oauth2callback',
  response_type='code')


class OAuthCalback(webapp2.RequestHandler):
    def get(self):
        # Get auth code
        auth_code = cgi.escape(self.request.get('code'))

        # Exchange auth code for credentials
        credentials = flow.step2_exchange(auth_code)

        # Get token from credentials
        auth2token = gdata.gauth.OAuth2Token(client_id=credentials.client_id,
          client_secret=credentials.client_secret,
          scope=SCOPE,
          access_token=credentials.access_token,
          refresh_token=credentials.refresh_token,
          user_agent='AppEngine-Google;(+http://code.google.com/appengine; appid: your_app_id)')

        # Construct client
        spreadsheets_client = gdata.spreadsheets.client.SpreadsheetsClient(source='https://your_app.appspot.com', auth_token=auth2token)

        # Authorize it
        auth2token.authorize(spreadsheets_client)

        # Spreadsheet key
        key = 'your_spreadsheet_key'

        # Add worksheet to the spreadsheet
        entry = spreadsheets_client.add_worksheet(key, 'test', 7, 10)


class MainHandler(webapp2.RequestHandler):
    def get(self):
        # Get url to start authorization
        auth_url = flow.step1_get_authorize_url()

        # Render link
        content = '<a style="display:inline" href="' + auth_url + ' "target="_blank">Authorize</a>'
        self.response.out.write(content)


app = webapp2.WSGIApplication([('/', MainHandler),
                                ('/oauth2callback', OAuthCalback),
                                ], debug=True)
导入webapp2
导入cgi
导入atom.data
导入gdata.data
导入gdata.spreadsheets.client
从oauth2client.client导入OAuth2WebServerFlow
范围=https://spreadsheets.google.com/feeds'
flow=OAuth2WebServerFlow(
client_id='your_client_id',
client_secret='your_client_secret',
范围=范围,
重定向https://your_app.appspot.com/oauth2callback',
响应(类型=“代码”)
类OAuthCalback(webapp2.RequestHandler):
def get(自我):
#获取身份验证代码
auth_code=cgi.escape(self.request.get('code'))
#交换凭据的身份验证代码
凭证=流程。步骤2\u交换(验证码)
#从凭据获取令牌
auth2token=gdata.gauth.OAuth2Token(client\u id=credentials.client\u id,
client\u secret=凭据。client\u secret,
范围=范围,
访问令牌=凭据。访问令牌,
刷新\u令牌=凭据。刷新\u令牌,
用户_agent='AppEngine-Google(+http://code.google.com/appengine;appid:your_app_id'))
#构造客户端
电子表格客户机=gdata.spreadsheets.client.spreadsheets客户机(source=)https://your_app.appspot.com,auth_token=auth2token)
#授权
auth2token.authorize(电子表格\客户端)
#电子表格键
key='您的电子表格\u key'
#将工作表添加到电子表格
条目=电子表格\客户端。添加\工作表(键“测试”,7,10)
类MainHandler(webapp2.RequestHandler):
def get(自我):
#获取url以启动授权
auth\u url=flow.step1\u get\u authorize\u url()
#渲染链接
内容=“”
self.response.out.write(内容)
app=webapp2.WSGIApplication([('/',MainHandler),
('/oauth2callback',OAuthcallback),
],debug=True)
关于OAuth,我将使用OAuth2WebServerFlow(有关更多信息,请参见[3])。凭据对象可以通过pickle进行序列化和反序列化。[4]中描述了存储凭证对象的更简单的方法

[1] -
[2] -
[3] -

[4] -

如果您想尝试,我使用oauth和gae。谢谢您的回复。我不能让它工作;我收到一个错误:
FlowExchangeError:credentials=flow上的请求无效。step2\u交换(身份验证码)
这很奇怪。。。如果单击同意屏幕上的“取消”,我可以重现此错误(请参阅)。请添加:
import logging
error=cgi.escape(self.request.get('error'))
logging.error(error)
就在凭证=flow.step2\u交换(身份验证码)
)。oauthclient也会进行日志记录,所以您应该可以在上看到它在应用程序日志的日志条目中失败的原因。你能分享一下吗?当我去的时候,我得到的错误信息跟你的图片几乎一样(除了实现的细节)。当我单击“授权”时,日志中不会生成错误,但我会被重定向到一个谷歌页面,上面写着“错误:无效的客户端”,下面写着“没有应用程序名”使用有关请求的一些信息Getting
FlowExchangeError:invalid_request
当直接访问app_name.appspot.com/oauth2callback时,应为/oauth2callback实现get方法处理程序,该处理程序应为请求中提供的授权代码。此处理程序设计为由处理OAuth的Google服务器调用。对于
错误:无效的\u客户端
,如果未设置同意屏幕,则会出现这种情况(例如)。此外,请确保为web应用设置了客户端ID,并且其重定向URI中填充了应用的重定向api(例如)。此外,请记住我提供的代码是用于引用的
oauth2callback
处理程序不应执行任何实际操作,而应构造、保存凭据对象并重定向到设计用于构造客户端和执行进一步操作的处理程序。