2

我们有一个使用 Google App Engine 作为后端的身份验证系统。底层语言和框架包括 Java、JDO、Google Authentication 和 Google App Engine。

我们有一个用户实体。用户实体是从 Google App Engine 身份验证响应中保存的用户元数据(例如:名字、姓氏、电子邮件地址)。

当用户尝试注册或登录(均为登录事件)时,我们会扫描数据存储以查看是否已存在具有相同电子邮件地址的用户。如果用户不存在,我们创建一个新用户。如果用户确实存在,我们会更新并检索他们的用户信息,然后检索他们的应用程序数据。

我们需要运行单独的多个事务,因为登录页面与应用程序页面完全分离。

在某些情况下,当用户尝试在短时间内注册两次时,会创建重复用户。虽然我们总是可以获取最后注册的用户,但我们确实希望查询是唯一的 JDO 查询。使用唯一的 JDO 查询,JDO 查询(在事务中运行)有时会由于找到两个相同的值(对于用户的电子邮件地址)而失败。

我们考虑了以下实施约束的方法:

  1. 将新注册的用户信息存储在缓存中。我们似乎没有找到任何信息表明缓存是防止重复的合适解决方案。缓存是否可以跨机器立即使用?即使是这样,缓存也可能出于各种原因弹出实体。
  2. 将用户的电子邮件存储在会话中。这似乎使代码膨胀,并且似乎是一种执行约束的奇怪方式。

Google App Engine 是否有最佳实践方法来防止身份验证工作流程中的重复值和单独的事务?

4

1 回答 1

4

我会推荐这两种方法的组合:

  1. 创建一个登录实体,该实体由用户的电子邮件和主要用户实体的 ID 组成。使用户的电子邮件成为登录实体中的键。这确保了它的独特性。

额外的好处是您可以将多个电子邮件地址链接到同一个用户实体。(我们将此选项作为我们应用程序中的一项功能)。

另一个额外的好处:您可以用呼叫替换您的登录查询,get()因为您可以从电子邮件地址创建一个密钥。这更便宜、更快,并且避免了最终的一致性问题(get call 总是一致的)。

  1. 在会话中存储电子邮件地址(甚至是简单的“登录”标志)。添加它并在每次登录尝试时检查它只需 3-5 行代码,所以我不会称它为“膨胀”。

在我的应用程序中,我向会话添加了一个标志,并在每次调用 App Engine 实例时检查此标志(不仅是登录调用,而且所有调用都需要额外的安全性),然后在用户注销时使会话无效。

于 2014-10-17T15:57:48.543 回答