Google app engine 向任务传递凭据
希望有人能帮忙。我正在Google app engine上构建一个应用程序,并尝试将经过身份验证的用户的凭据传递给推送任务处理程序。我正在使用OAuth2DecoratorFromClientSecrets库创建装饰器,它似乎将用户的凭据存储在数据存储中。它用一个类似“1101119131222157971566”的键名来存储它。我的问题是,我似乎找不到一种方法来弄清楚这个键名是什么,这样我就可以使用StorageByKeyName方法从我的worker处理程序中检索它。我读过的文档使用user\u id作为密钥名,但这对我不起作用,因为凭据不是以user\u id作为密钥名存储的,但是如果我硬编码密钥名,那么代码确实起作用。我知道我可以从提交处理程序中运行复制代码,但需要将其作为单独的任务运行。以下是我的代码示例,感谢您提供的帮助:Google app engine 向任务传递凭据,google-app-engine,google-oauth,Google App Engine,Google Oauth,希望有人能帮忙。我正在Google app engine上构建一个应用程序,并尝试将经过身份验证的用户的凭据传递给推送任务处理程序。我正在使用OAuth2DecoratorFromClientSecrets库创建装饰器,它似乎将用户的凭据存储在数据存储中。它用一个类似“1101119131222157971566”的键名来存储它。我的问题是,我似乎找不到一种方法来弄清楚这个键名是什么,这样我就可以使用StorageByKeyName方法从我的worker处理程序中检索它。我读过的文档使用user
JINJA_ENVIRONMENT = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
extensions=['jinja2.ext.autoescape'],
autoescape=True)
SCOPES =['https://www.googleapis.com/auth/drive']
decorator = OAuth2DecoratorFromClientSecrets(
os.path.join(os.path.dirname(__file__),
'client_secrets.json'),
' '.join(SCOPES)
)
class MainPage(webapp2.RequestHandler):
def get(self):
if users.get_current_user():
url = users.create_logout_url(self.request.uri)
url_linktext = 'Logout'
template_values = {'url': url,
'url_linktext': url_linktext,
}
template = JINJA_ENVIRONMENT.get_template('index.html')
self.response.write(template.render(template_values))
else:
self.redirect(users.create_login_url(self.request.uri))
class Submit(webapp2.RequestHandler):
@decorator.oauth_required
def post(self):
taskqueue.add(url='/worker', params={'user_id' : users.get_current_user().user_id()})
self.response.write('<html><body>You wrote:<pre>')
self.response.write(users.get_current_user().user_id())
self.response.write('</pre></body></html>')
class Worker(webapp2.RequestHandler):
def post(self):
user_id = self.request.get('user_id')
credentials = StorageByKeyName(CredentialsModel, user_id , 'credentials').get()
http = httplib2.Http()
http = credentials.authorize(http)
service = build('drive', 'v2',http=http)
fileId = 'actual file_id of drive file here'
copied_file = {'title': 'My New Test Doc2'}
new_file = service.files().copy(fileId=fileId,body=copied_file).execute(http=http)
application = webapp2.WSGIApplication([
('/', MainPage),
('/submit', Submit),
('/worker', Worker),
(decorator.callback_path, decorator.callback_handler()),
], debug=True)
JINJA_ENVIRONMENT=jinja2.ENVIRONMENT(
loader=jinja2.FileSystemLoader(os.path.dirname(_文件__)),
扩展=['jinja2.ext.autoescape'],
自动转义=真)
作用域=['https://www.googleapis.com/auth/drive']
decorator=OAuth2DecoratorFromClientSecrets(
join(os.path.dirname(_文件__),
“client_secrets.json”),
''.join(范围)
)
类主页(webapp2.RequestHandler):
def get(自我):
if users.get_current_user():
url=users.create\u logout\u url(self.request.uri)
url\u linktext='Logout'
模板_值={'url':url,
“url\u linktext”:url\u linktext,
}
template=JINJA_环境。获取_模板('index.html'))
self.response.write(template.render(template_值))
其他:
重定向(users.create\u login\u url(self.request.uri))
类提交(webapp2.RequestHandler):
@需要decorator.oauth_
def post(自我):
taskqueue.add(url='/worker',params={'user\u id':users.get\u current\u user().user\u id()})
self.response.write('youwrite:')
self.response.write(users.get_current_user().user_id())
self.response.write(“”)
类工作程序(webapp2.RequestHandler):
def post(自我):
user\u id=self.request.get('user\u id')
credentials=StorageByKeyName(CredentialsModel,用户id,'credentials')。get()
http=httplib2.http()
http=凭据。授权(http)
服务=构建('drive','v2',http=http)
fileId='实际文件\此处驱动器文件的id'
复制的_文件={'title':'mynewtestdoc2'}
new_file=service.files().copy(fileId=fileId,body=copied_file)。执行(http=http)
application=webapp2.WSGIApplication([
(“/”,主页),
(“/提交”,提交),
(“/工人”,工人),
(decorator.callback\u路径,decorator.callback\u处理程序()),
],debug=True)
首先,删除顶层的http=decorator.http
——它似乎没有被使用,只能从修饰的方法内部使用
我不确定,但看看装饰器代码,我认为它是基于用户\ id()的键控。您的代码正在显示,但您传递给任务的参数没有显示。请尝试
{'user\u id':users.get\u current\u user().user\u id()}
谢谢您的帮助。我已经删除了http=decorator.http,并进行了您建议的更改,但不幸的是,它没有帮助。为了给您提供更多的上下文,问题在于行credentials=StorageByKeyName(CredentialsModel,user_id,'credentials')。get()
。如果我将其更改为credentials=StorageByKeyName(CredentialsModel,'1101119131222157971566','credentials').get()
,则它会起作用,因为凭据是以该密钥名存储的,而不是以用户id作为密钥存储的。问题是,当用户第一次进行身份验证时,我无法知道该密钥名。我要说的是,您实际上并没有将用户id传递给该方法。添加taskqueue:taskqueue.add(url='/worker',params={'user_id':users.get_current_user()})的行需要更改以传递用户id,而不是用户对象:taskqueue.add(url='/worker',params={'user_id':users.get_current_user().user_id()})如果您已经进行了更改,你能更新上面问题中的完整代码吗?是的,我明白你的意思,我已经用你的建议更新了上面的代码。老实说,在提交处理程序中,我正在将users.get\u current\u user().user\u id()
打印到屏幕上,它不会返回任何内容,而users.get\u current\u user()
实际上会返回我的电子邮件地址,但除此之外,由于某些原因,凭据没有以用户id作为密钥名存储,这就是为什么我无法使用StorageByKeyName
方法从存储中检索凭据并将用户id传递给它。如果我将密钥名传递给它11011191312157971566
,那么它工作正常。您是在本地测试还是部署测试?我已经看到用户服务和oauth2decorator之间的交互在本地做了一些意想不到的事情。我可以通过调用StorageByKeyName(CredentialsModel,users.get_current_user().user_id(),'credentials')来确认已部署的应用程序能够成功地获取凭据对象。get()。抱歉,您实际上是对的。我忘记了在调用user_id()方法时包含()。现在可以了。我已经更新了上面的代码,所以它现在是正确的。谢谢你的帮助。