【发布时间】:2012-07-22 20:00:41
【问题描述】:
我正在开发一个主要通过应用访问的网站,我想使用 OAuth2 进行用户注册和身份验证。由于它是一个 Android 应用程序,我将开始使用 Google 的 OAuth2 东西,因为它在 Android 上提供了不错的 UI。
Google 声明 "You can choose to use Google's authentication system as a way to outsource user authentication for your application. This can remove the need to create, maintain, and secure a username and password store." 这是我想要做的。 但是当我浏览他们的所有示例时,我只能找到关于让网站或应用针对 Google 服务对用户进行身份验证的内容。
确实,当我使用 Google 的 OAuth2 注册我的应用程序(“客户端”)时,可以选择网站客户端和“已安装”客户端(即移动应用程序),但不能同时使用两者。我可以创建两个单独的客户端,但我阅读了 OAuth2 草案,我认为会有一个问题,我现在将对此进行解释。
这是我设想的工作方式:
- 用户要求 MyApp 访问他的私人数据。
- 应用使用 Android 的
AccountManager类为 Google 的 API 请求访问令牌。 - Android 对用户说“应用程序 'MyApp' 想要访问您在 Google 上的基本信息。这样可以吗?”
- 用户说是。
-
AccountManager使用手机上存储的凭据连接到 Google 的 OAuth2 服务器,并要求提供访问令牌。 - 返回访问令牌(绿线后面)。
-
AccountManager将访问令牌返回给 MyApp。 - MyApp 向 MySite 发送请求以获取用户的私人数据,包括访问令牌。
- MySite 需要使用访问令牌验证用户。它使用 Google 验证令牌 as described here -“Google,此令牌有效吗?”。
- 现在,我想要发生的是 Google 说“是的,给你的确实是那个用户。”,但我认为实际会发生(基于 OAuth2 草案和Google 的文档)是它会说“没门!那个令牌只对 MyApp 有效,而你是 MySite。GTFO!”。
那么我该怎么做呢?请不要说“使用 OpenID”或“不要使用 OAuth2”或其他类似无益的答案。哦,我真的很想继续使用漂亮的AccountManager UI,而不是糟糕的弹出窗口WebViews
编辑
来自 Nikolay 的临时答案(如果它有效,我会报告!)是它应该确实有效,而且 Google 的服务器不会关心访问令牌来自哪里。对我来说似乎有点不安全,但我会看看它是否有效!
更新
我用 Facebook 而不是 Google 实现了这个模式,它完全有效。 OAuth2 服务器不关心访问令牌的来源。至少 Facebook 没有,所以我认为 Google 也没有。
鉴于此,存储访问令牌是一个非常非常糟糕的主意!但我们也不想访问 Facebook/Google 的服务器来检查 每个 请求的身份验证,因为它会减慢一切速度。最好的办法可能是为您的站点添加一个额外的身份验证 cookie,在验证访问令牌时分发该 cookie,但更简单的方法是将访问令牌视为密码并存储它的哈希值。你也不需要加盐,因为访问令牌真的很长。所以上面的步骤变成了这样:
9。 MySite 需要使用访问令牌验证用户。首先,它检查其哈希有效访问令牌的缓存。如果在那里找到令牌的散列,则它知道用户已通过身份验证。否则,它会通过 Google as described here 与 Google 进行检查 - “Google,此令牌有效吗?”。
10。如果 Google 说访问令牌无效,我们会告诉用户 GTFO。否则谷歌会说“是的,这是一个有效的用户”,然后我们检查我们的注册用户数据库。如果找不到该 Google 用户名(或 Facebook id,如果使用 Facebook),我们可以创建一个新用户。然后我们缓存访问令牌的哈希值。
【问题讨论】:
-
很好奇 - 上述方法最终对你有用吗?
-
查看更新的问题:它至少对 Facebook 有效。
-
我也以这种方式实现了它,它正在工作。 Google API、Android 上的 Google Play 服务,以及在我的 Spring3 应用程序的服务器端重用令牌。
-
+1 得到很好解释的问题,包括非常有用的图表。想再给一个 +1 来分享结果...
-
谢谢。我没有添加的一个更新:facebook 实际上确实建议将访问令牌存储在数据库中,因为您需要它们在 facebook 服务器上执行操作(假设您愿意)。存储密码可能不是一个坏主意,因为如果数据库遭到破坏(并且您意识到),您可以使所有泄露的访问令牌无效。
标签: android oauth oauth-2.0 google-authentication