Oauth 相关的流程问题
问题描述:在使用支持OAuth的装饰器调用方法时,出现了一个非类型错误。
我查看了这个页面:https://developers.google.com/api-client-library/python/guide/google_app_engine
具体来说,我关注的是指南中的代码,内容如下:在下面的代码片段中,使用了OAuth2DecoratorFromClientSecrets类来创建一个支持OAuth的装饰器,然后将这个装饰器应用到一个访问Google任务API的函数上:
我尝试创建一个类似的东西(见下文)。
我的应用程序出现了这个错误:
Traceback (most recent call last):
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1535, in __call__
rv = self.handle_exception(request, response, e)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1529, in __call__
rv = self.router.dispatch(request, response)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1278, in default_dispatcher
return route.handler_adapter(request, response)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 1102, in __call__
return handler.dispatch()
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 572, in dispatch
return self.handle_exception(e, self.app.debug)
File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/webapp2-2.5.2/webapp2.py", line 570, in dispatch
return method(*args, **kwargs)
File "/base/data/home/apps/APPNAME/DIRECTORYNAME/main.py", line 39, in get
url = decorator.authorize_url()
File "/base/data/home/apps/APPNAME/DIRECTORYNAME/oauth2client/appengine.py", line 798, in authorize_url
url = self.flow.step1_get_authorize_url()
AttributeError: 'NoneType' object has no attribute 'step1_get_authorize_url'
当我执行logging.info(decorator)时,它返回:
然后当我执行:
>>>logging.info(dir(decorator))
>>> ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_auth_uri', '_callback_path', '_client_id', '_client_secret', '_create_flow', '_credentials_class', '_credentials_property_name', '_display_error_message', '_in_error', '_kwargs', '_message', '_revoke_uri', '_scope', '_storage_class', '_tls', '_token_response_param', '_token_uri', '_user_agent', 'authorize_url', 'callback_application', 'callback_handler', 'callback_path', 'credentials', 'flow', 'get_credentials', 'get_flow', 'has_credentials', 'http', 'oauth_aware', 'oauth_required', 'set_credentials', 'set_flow']
但是像decorator.http()或decorator.has_credentials()这样的任何方法都会触发一个非类型错误。
我的代码:
import webapp2
import logging
import jinja2
import pprint
import os
import json
import time
import httplib2
from apiclient.discovery import build
from apiclient.errors import HttpError
from google.appengine.ext.webapp.util import run_wsgi_app
from oauth2client.appengine import OAuth2DecoratorFromClientSecrets
from oauth2client.client import AccessTokenRefreshError
from oauth2client.client import OAuth2WebServerFlow
from oauth2client.client import flow_from_clientsecrets
from oauth2client.file import Storage
from oauth2client.tools import run
from google.appengine.api import urlfetch
decorator = OAuth2DecoratorFromClientSecrets(
os.path.join(os.path.dirname(__file__), 'client_secrets.json'),
scope='https://www.googleapis.com/auth/bigquery')
# Google App Engine project ID
PROJECT_NUMBER = 'XXXXXXXXXXXXX'
bigquery_service = build('bigquery', 'v2')
class MainHandler(webapp2.RequestHandler):
def get(self):
if decorator.has_credentials():
logging.info('has credentials')
else:
logging.info('bouncing credentials')
logging.info(decorator)
url = decorator.authorize_url()
return self.redirect(url)
jinja_environment = self.jinja_environment
template = jinja_environment.get_template("/index.html")
self.response.out.write(template.render())
@property
def jinja_environment(self):
jinja_environment = jinja2.Environment(
loader=jinja2.FileSystemLoader('views')
)
return jinja_environment
app = webapp2.WSGIApplication([
('/', MainHandler),
(decorator.callback_path, decorator.callback_handler()),
], debug=True)
1 个回答
2
从查看源代码来看,我觉得“装饰器”应该是在你使用某个东西之前,先给它加上一些功能。在这个例子中,你可能想要用 oauth_aware
来装饰 get
。
class MainHandler(webapp2.RequestHandler):
@decorator.oauth_aware
def get(self):
if decorator.has_credentials():
...
else:
...
url = decorator.authorize_url()