Python Twitter使用GoogleAppEngine BadKeyError填充错误

时间:2013-11-18 07:36:55

标签: python google-app-engine twitter

我正在使用GoogleAppEngine尝试创建一个需要使用Twitter登录的简单应用。我的问题是,当我将用户重定向到我的情况下某种类型的“确认”页面/配置文件时 - 我收到了一个坏键错误,因为我将用户身份验证数据保存到我的db.Model中。

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)

login.html只是一个将您重定向到/ signin

的按钮

我得到的错误是:

BadKeyError: Invalid string key TwitterUserNameHere===. Details: Incorrect padding

还有一种方法可以在我将用户重定向到/ 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

1 个答案:

答案 0 :(得分:0)

回溯显示您的错误发生在ProfilePage。现在,在AuthorizeTwitter profile = Profile.get_by_key_name(screenname)你正确地做ProfilePage - 但在profile = Profile.get(screenname)你做get_by_keyname。这假设“screenname”是整个字符串键,它不是,因此是错误。在那里也使用{{1}}。

将屏幕名称保存为模块级全局会在一次有多个用户时引发各种问题。相反,您应该将其作为URL参数传递:您将从授权处理程序重定向到配置文件一,因此您应该将Twitter句柄作为URL参数传递给配置文件功能。 webapp2文档展示了如何做到这一点。