Python Twitter使用GoogleAppEngine BadKeyError填充不正确
我正在使用GoogleAppEngine尝试制作一个简单的应用程序,需要使用Twitter登录。我的问题是,在我的例子中,当我将用户重定向到某种类型的“确认”页面-/profile时,我得到了一个坏键错误,因为我将用户身份验证数据保存到了我的db.Model中Python Twitter使用GoogleAppEngine BadKeyError填充不正确,python,google-app-engine,twitter,Python,Google App Engine,Twitter,我正在使用GoogleAppEngine尝试制作一个简单的应用程序,需要使用Twitter登录。我的问题是,在我的例子中,当我将用户重定向到某种类型的“确认”页面-/profile时,我得到了一个坏键错误,因为我将用户身份验证数据保存到了我的db.Model中 import logging import webapp2 from google.appengine.ext import db from google.appengine.ext.webapp import template impo
import logging
import webapp2
from google.appengine.ext import db
from google.appengine.ext.webapp import template
import urlparse
import oauth2 as oauth
consumer_key='MY_CONSUMER_KEY'
consumer_secret='SECRET_KEY'
request_token_url='https://api.twitter.com/oauth/request_token'
access_token_url='https://api.twitter.com/oauth/access_token'
authorize_url='https://api.twitter.com/oauth/authorize'
consumer=oauth.Consumer(consumer_key,consumer_secret)
client = oauth.Client(consumer)
screenname = ''
class Profile(db.Model):
twitter_id = db.StringProperty()
access_token = db.StringProperty()
access_token_secret = db.StringProperty()
twitter_user_name = db.StringProperty()
class MainHandler(webapp2.RequestHandler):
def get(self):
self.response.out.write(template.render("login.html", {}))
class SignInWithTwitter(webapp2.RequestHandler):
def get(self):
resp, content = client.request(request_token_url, "GET")
self.request_token = dict(urlparse.parse_qsl(content))
self.redirect((authorize_url +'?oauth_token='+ self.request_token['oauth_token']))
class ProfilePage(webapp2.RequestHandler):
def get(self):
logging.info("tst" + screenname)
self.profile = Profile.get(screenname)
self.response.out.write("<h1> Hello " + self.profile.screenname +"<h1>")
class AuthorizeTwitter(webapp2.RequestHandler):
def get(self):
oauth_verifier = self.request.get("oauth_verifier")
token = oauth.Token(self.request.get('oauth_token'), self.request.get('oauth_token_secret'))
token.set_verifier(oauth_verifier)
client = oauth.Client(consumer, token)
resp, content = client.request(access_token_url, "POST")
access_token = dict(urlparse.parse_qsl(content))
oauth_token = access_token['oauth_token']
oauth_token_secret = access_token['oauth_token_secret']
userid = access_token['user_id']
global screenname
screenname = access_token['screen_name']
logging.info(screenname)
profile = Profile.get_by_key_name(screenname)
if profile is None:
profile = Profile(key_name = screenname)
profile.twitter_id = userid
profile.access_token = oauth_token
profile.access_token_secret = oauth_token_secret
profile.twitter_user_name = screenname
profile.save()
self.redirect("/profile")
application = webapp2.WSGIApplication([
('/', MainHandler),
('/signin', SignInWithTwitter),
('/services/twitter/authorized', AuthorizeTwitter),
('/profile', ProfilePage),
], debug=True)
还有没有一种方法可以在我将用户重定向到/profile后获取当前登录的配置文件?或者我需要继续使用我的全局screenname变量访问我的数据库吗
编辑
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/s~howaggieru/1.371718316886323623/main.py", line 56, in get
self.profile = Profile.get(screenname)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/db/__init__.py", line 1238, in get
results = get(keys, **kwargs)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/db/__init__.py", line 1533, in get
return get_async(keys, **kwargs).get_result()
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/db/__init__.py", line 1492, in get_async
keys, multiple = datastore.NormalizeAndTypeCheckKeys(keys)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/datastore.py", line 178, in NormalizeAndTypeCheckKeys
keys = [_GetCompleteKeyOrError(key) for key in keys]
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/datastore.py", line 2782, in _GetCompleteKeyOrError
key = Key(arg)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/datastore_types.py", line 371, in __init__
'Invalid string key %s. Details: %s' % (encoded, e))
BadKeyError: Invalid string key TwitterUsername===. Details: Incorrect padding
回溯显示您的错误发生在
ProfilePage
中。现在,在AuthorizeTwitter
中,您正确地执行了profile=profile.get(屏幕名)
-但在ProfilePage
中,您执行了profile=profile.get(屏幕名)
。这假设“screenname”是整个字符串键,而不是,因此出现了错误。在那里也使用get\u by\u keyname
如果一次有多个用户,将屏幕名保存为模块级全局名称将导致出现各种问题。相反,您应该将其作为URL参数传递:您正在从授权处理程序重定向到概要文件,因此您应该将twitter句柄作为URL参数传递给概要文件函数。webapp2文档展示了如何做到这一点。您能否发布整个回溯,其中显示了错误产生的位置?(与您的错误无关,但您肯定不希望
screenname
成为一个全局变量。)我已经添加了整个回溯。我怎样才能在不使屏幕名全球化的情况下继续这样做呢
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/s~howaggieru/1.371718316886323623/main.py", line 56, in get
self.profile = Profile.get(screenname)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/db/__init__.py", line 1238, in get
results = get(keys, **kwargs)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/db/__init__.py", line 1533, in get
return get_async(keys, **kwargs).get_result()
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/db/__init__.py", line 1492, in get_async
keys, multiple = datastore.NormalizeAndTypeCheckKeys(keys)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/datastore.py", line 178, in NormalizeAndTypeCheckKeys
keys = [_GetCompleteKeyOrError(key) for key in keys]
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/datastore.py", line 2782, in _GetCompleteKeyOrError
key = Key(arg)
File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/datastore_types.py", line 371, in __init__
'Invalid string key %s. Details: %s' % (encoded, e))
BadKeyError: Invalid string key TwitterUsername===. Details: Incorrect padding