2012-04-04 114 views
7

几个月前我从Google App Engine迁移出去。但是我仍然依靠它进行身份验证,因为我的用户在GAE上通过其user_id属性进行标识。将用户从Google App Engine迁移到Google OpenID

为此,我的(现在是外部的)应用程序使用加密,签名和时间戳登录请求将用户重定向到Google App Engine应用程序。 GAE应用程序然后使用GAE的“用户”服务执行登录。在GAE上成功登录后,用户将再次使用加密的,带符号和时间戳的响应重定向到我的外部应用程序。 基本的实现可以找到herehere。正如你所看到的,这是非常基本的,并且依赖于沉重的加密导致性能不佳。

我的外部应用程序(在本例中为Django应用程序)将user_id存储在用户表的密码字段中。除了user_id之外,我只能从GAE获取电子邮件地址,以在Django中存储用户名和电子邮件。

现在我想删除对GAE服务的依赖。想到的第一种方法可能是向每个用户发送一封电子邮件,要求他设置一个新密码,然后使用Django执行我自己的认证。

我更喜欢依靠Google的OpenID服务的解决方案,这样用户实际上没有区别。这也是首选,因为我需要将用户发送给Google,以获取Google Calendar API的AuthSub令牌。

问题是,我找不到一种方法可以在不使用GAE的情况下获取给定Google帐户的GAE user_id属性。 OpenID和所有其他身份验证协议使用不同的标识符。

所以,现在的问题是:Google是否提供了我可以用于此目的的API,但我还没有看到?有没有其他可能的解决方案或想法如何迁移用户帐户?

在此先感谢!

回答

1

AFAIK是Google帐户与Google OpenID之间唯一的通用标识符,即电子邮件。

  1. 当用户通过当前的gae设置登录到Google帐户时获取电子邮件。使用User.email()。保存此电子邮件以及用户数据。

  2. 当您收到所有(大部分)用户的电子邮件时,请切换到Google OpenID。用户登录时,获取电子邮件地址并在数据库中找到该用户。

+0

感谢您的回复。与此相关的问题是,用户可能在此期间更改了他的电子邮件地址,例如,从非gmail地址转换为gmail或另一个非gmail地址。我之前遇到过这种情况,必须手动提供一种方式让用户与我联系并重新链接其旧帐户和相关数据。 user_id是一个永不改变的静态标识符,我真的很想确保没有人被抛在后面。 – mback2k 2012-04-04 14:34:49

0

Google有一个唯一的标识符,该标识符作为一个成功的OpenID身份验证请求参数返回 - * openid.claimed_id *。如果切换到使用OpenID,那么在用户第一次使用新方法登录时,您可以基本上交换user_id作为此参数,而用户不会注意到他们的登录体验不同。

概述认证过程的文档here。我建议使用混合OpenID + OAuth方法,以便您可以将您的请求令牌与给定ID相关联,然后在返回时验证openid.claimed_id是否匹配您的原始请求令牌。

+0

谢谢。是的,但我如何将现有用户与他们的帐户相匹配。重点是电子邮件地址或昵称不是唯一的,也不是静态的。我用户群中有近15%的人使用非gmail/googlemail.com地址,这些地址在任何时候都可能发生变化。 我目前使用user_id作为用户识别的单一因素,但为了信息和联系目的而保留电子邮件和昵称。 – mback2k 2012-04-04 19:42:22

+0

两种可能的方法。其一,您只需将您系统上的帐户与第一次登录的任何Google帐户关联起来。两个(更安全)在过渡期间首先使用当前方法验证用户,然后再次使用OpenID方法验证用户。 – 2012-04-04 20:26:04

+0

要增加/澄清的另一件事 - 在开始转换之前,您应该为用户生成自己的唯一标识符,并且不要依赖Google标识符来验证未来基于OpenID的身份验证之外的其他任何操作。 – 2012-04-04 20:36:49

2

要做到这一点,最好的方法是向用户展示“迁移”interstital,将其重定向到Google OpenID提供商并提示他们登录。一旦他们在两个地点都登录,您可以匹配这两个帐户,并让他们将来通过OpenID登录。

+0

感谢您的回答,但正如我现在在其他评论中指出的:我真的很想避免过渡阶段,迁移期或类似的事情。而且我也想确保没有人落在后面。 (我知道你的解决方案是好的,但其他人可能不会。)我应该补充的一件事是,即使我将user_id存储在我的Django auth_user表的密码字段中,user_id也未加密或散列。如果一个API将它们转换为OpenID标识符或类似的东西存在,我可以轻松迁移。 – mback2k 2012-04-05 06:08:30

+0

@ mback2k你在找什么不存在。 App Engine用户API返回的用户ID是一个内部标识符;没有外部通信或任何将其转换为外部标识符的方式。 – 2012-04-05 06:10:42

+0

好吧,我明白了。感谢你的回答。这可能是GAE团队未来可能正在研究的问题吗?作为开放数据导入/导出和迁移工作的一部分? – mback2k 2012-04-05 06:14:57

1

你为什么不尝试一种混合的方法:

  1. 切换至OpenID
  2. 如果您的应用已经知道用户id,你做
  3. 如果不询问用户,如果他有一个帐户迁移
  4. 如果是的话,请登录他与老mechansim和ttransfer的acount
  5. 如果没有创建一个新帐户