1

我正在写一个代表注册用户离线访问Google API的应用程序。注册过程收集基本帐户信息,例如Business Name,Contact Eamil等。然后通过OAuth2进程接收用户,最终获得用户的OAuth2凭证。我想将所有这些数据,公司名称,联系人电子邮件和OAuth2凭证保存在同一个数据存储实体中。但是,当我尝试调用Model.put()时,出现这个奇怪的错误;在Google App-Engine数据存储中存储客户端oauth2凭证

BadValueError: Property credentials must be convertible to a Credentials instance (<oauth2client.client.OAuth2Credentials object at 0xb595facc>)

我的Oauth回调函数如下所示。你可以看到我尝试过使用StorageByKeyName(),但它给出了相同的错误。

注意我不确定这是否重要,但在我调用ua.put()时,实体尚未创建。我已经看到其他非常类似的代码,其中实体在分配credentials属性时已经存在。

class Oauth2callback(BaseHandler): 
    def get(self): 
     user = users.get_current_user() 
     flow = pickle.loads(memcache.get(user.user_id())) 
     if flow: 
      # Store UserAccount 
      credentials = flow.step2_exchange(self.request.params) 
      pa = models.ParentAccount.get_account_by_token('XXXXXXXXXX') 
      ua = models.UserAccount(
       key_name  = user.user_id(), 
       account_email = user.email(), 
       parent_account = pa, 
       credentials  = credentials, 
      ) 
      ua.put() 

      # Try Storing Credentials Separately 
      # credentials = flow.step2_exchange(self.request.params) 
      # storage = StorageByKeyName(models.UserAccountCredentials, user.user_id(), 'credentials') 
      # storage.put(credentials) 

感谢

这里的模型定义。

class UserAccount(db.Model): 
    status_states  = ["IN-ACTIVE","ACTIVE", "PAUSED", "DELETED"] 

    account_email  = db.StringProperty(required=False) 
    contact_email  = db.StringProperty(required=False) 
    business_name  = db.StringProperty(required=False) 
    create_date   = db.DateTimeProperty(auto_now_add=True) 
    account_settings = db.StringProperty(required=False) # JSON config data MAX 500 characters. Change type: 'Text' for larger values and to avoid indexing. 
    parent_account  = db.ReferenceProperty(ParentAccount, collection_name = "children", required=False) 
    status    = db.StringProperty(required=True, default = "ACTIVE", choices=set(status_states)) 
    original_status  = db.StringProperty(required=True, default = "ACTIVE", choices=set(status_states)) 
    credentials   = CredentialsProperty(required=False) 
+0

你能提供你的模型定义吗?另外,你应该使用'OAuth2Decorator'。你参考了哪些文档? – bossylobster

+1

谢谢。刚刚添加了模型定义。我不确定这段代码涉及哪些文档。那里有这么多,很难知道要跟随哪个方向。我从另一个工作项目中拿出了这个代码,这是我没有写的。 另一方面,我偶然发现了Google的API快速启动小部件[这里](https://developers.google.com/api-client-library/python/start/installation#appengine),它生成的代码完美无缺,尽管它将凭证保存在自己的模型中。这对我来说很好,但我仍然很好奇为什么这不起作用。 –

回答

0

我认为序列化证书可能存在问题。我正在正确地酸洗OAuth2Credentials对象来存储它。 我会更新这个,如果我找到一个解决方案。

更新使用OAuth2Credentials.to_json()获取对象的可序列化版本from_json()以将其转换回来。存储纯文本可能会导致安全问题。如果您需要领导开始,请参阅会议的Flask文档以获取更多信息。

+0

同意。更新了我找到的答案。 – mehmetg