我将解释我最终是如何做到这一点的,以防它帮助其他人。
我称我的用户为 manager,我为每个用户都有一个 Manager 实体:
class Manager(ndb.Model):
user_account = ndb.StructuredProperty(UserAccount))
linked = ndb.BooleanProperty(default=False)
user = ndb.UserProperty()
user 属性是我将删除的旧用户服务帐户。 user_account 属性存储信息以识别 Oauth2 帐户:
class UserAccount(ndb.Model):
provider = ndb.StringProperty(required=True)
id = ndb.StringProperty(required=True)
name = ndb.StringProperty()
email = ndb.StringProperty()
基本上,对于每个经理,我想为user_account(Oauth2 登录)设置一个值并删除user(旧用户帐户)。我希望以最小的经理负担来做到这一点。
当用户最近使用旧用户帐户登录时,该 cookie 仍将处于活动状态。但是,现在用户正在使用 Oauth2 帐户登录。使用 Oauth2 登录后,我们检查旧的用户帐户 cookie 是否仍然处于活动状态。如果是这样,我们会自动合并帐户。这是处理程序的草图。
class ManagerPage(webapp2.RequestHandler):
def get(self):
# This returns a Manager entity after the user has logged in with
# Oauth2. If the user is logging in for the first time, this will
# be a blank Manager entity.
self.get_manager()
# Temporary processing to link accounts. If the user is still logged
# as a Google user (because that cookie hasn't expired), then we
# automatically transfer their old information to the new Manager
# entity. In doing the conversion below, manager.linked is set to
# True so this can't happen more than once. Now that the Manager
# entity has been updated, redirect back to the same page.
gae_user = users.get_current_user()
if not manager.linked and gae_user:
manager.convert_old_manager(gae_user)
self.redirect("/manager")
# Present info to the manager
...
template = JINJA_ENVIRONMENT.get_template("manager.html")
self.response.write(template.render(template_values))
如果旧用户帐户 cookie 未激活,那么我在上面的管理器页面中有一个链接,要求用户将旧帐户与新帐户链接。当用户使用旧账号登录时,会被重定向到上面的Manager Page,并自动关联账号。