66

我正在开发一个主要通过应用程序访问的网站,并且我想使用 OAuth2 进行用户注册和身份验证。由于它是一个 Android 应用程序,我将开始使用 Google 的 OAuth2 东西,因为它在 Android 上提供了不错的 UI。

谷歌声明“你可以选择使用谷歌的身份验证系统来为你的应用程序外包用户身份验证。这可以消除创建、维护和保护用户名和密码存储的需要。” 这就是我想要做的。但是,当我浏览他们的所有示例等等时,我只能找到有关让网站应用程序根据 Google 的服务对用户进行身份验证的内容。

事实上,当我使用 Google 的 OAuth2 注册我的应用程序(“客户端”)时,可以选择网站客户端和“已安装”客户端(即移动应用程序),但不能同时使用两者。我可以创建两个单独的客户端,但我阅读了 OAuth2 草案,我认为会有一个问题,我现在将对此进行解释。

以下是我设想它的工作方式:

OAuth2流程图

  1. 用户要求 MyApp 访问他的私人数据。
  2. 应用程序使用 Android 的AccountManager类来为 Google 的 API 请求访问令牌。
  3. Android 对用户说“应用程序‘MyApp’想要访问您在 Google 上的基本信息。可以吗?”
  4. 用户说是。
  5. AccountManager使用存储在手机上的凭据连接到 Google 的 OAuth2 服务器,并要求提供访问令牌。
  6. 返回访问令牌(跟随绿线)。
  7. AccountManager将访问令牌返回给 MyApp。
  8. MyApp 向 MySite 发送请求以获取用户的私有数据,包括访问令牌。
  9. MySite 需要使用访问令牌验证用户。它使用 Google 验证此处描述的令牌- “Google,此令牌有效吗?”。
  10. 现在,我想要发生的是谷歌说“是的,给你的人确实是那个用户。”,但我认为实际会发生的事情(基于 OAuth2 草案和谷歌的文档)是它会说“不方式!该令牌仅对 MyApp 有效,而您是 MySite。GTFO!”。

那么我该怎么做呢?请不要说“使用 OpenID”或“不要使用 OAuth2”或其他类似无益的答案。哦,我真的很想继续使用漂亮的AccountManagerUI 而不是蹩脚WebView的popup

编辑

来自 Nikolay 的临时答案(如果它有效,我会报告!)是它应该真正有效,而且 Google 的服务器不会关心访问令牌来自哪里。对我来说似乎有点不安全,但我会看看它是否有效!

更新

我用 Facebook 而不是 Google 实现了这个模式,它完全有效。OAuth2 服务器不关心访问令牌的来源。至少 Facebook 没有,所以我认为 Google 也没有。

鉴于此,存储访问令牌是一个非常非常糟糕的主意!但是我们也不想访问 Facebook/Google 的服务器来检查每个请求的身份验证,因为它会减慢一切。最好的办法可能是为您的站点添加一个额外的身份验证 cookie,在验证访问令牌时分发该 cookie,但更简单的方法是将访问令牌视为密码并存储它的哈希值。你也不需要加盐,因为访问令牌真的很长。所以上面的步骤变成了这样:

9. MySite 需要使用访问令牌验证用户。首先,它检查其哈希有效访问令牌的缓存。如果在那里找到令牌的散列,则它知道用户已通过身份验证。否则,它会按照此处所述与 Google 进行检查,使用 Google -“Google,此令牌有效吗?”。

10. 如果 Google 说访问令牌无效,我们会告诉用户 GTFO。否则谷歌会说“是的,这是一个有效的用户”,然后我们检查我们的注册用户数据库。如果找不到该 Google 用户名(或 Facebook id,如果使用 Facebook),我们可以创建一个新用户。然后我们缓存访问令牌的哈希值。

4

6 回答 6

5

我刚刚发布了一个类似 StackOverflow 问题的答案。

Google 将此称为混合应用程序,并解释了“Android 应用程序如何获得 Web 后端的离线访问”

它的要点是,您必须将经过按摩的scope字符串传递GoogleAuthUtil.getToken到其中才能使其返回授权码(而不是 OAuth2 令牌)。根据此原理图,该授权代码可以从您的移动应用程序传递到您的服务器,并交换为 OAuth2 令牌和刷新令牌。

scope参数需要看起来像这样:

oauth2:server:client_id:<your_server_client_it>:api_scope:<scope_url_1> <scope_url_2> ...
于 2013-07-12T02:22:08.140 回答
2

您可以在其他任何地方使用移动应用程序检索到的访问令牌。Drive SDK 有一个漂亮而简单的介绍,贯穿https://developers.google.com/drive/quickstart-android上的流程

于 2013-04-30T17:54:55.503 回答
1

您可能需要 OpenID Connect,它使用 OAuth 令牌进行身份验证。至于AccountManager,目前的 OAuth 支持有点老套,新的Google Play 服务,即将发布,希望能做得更好。请参阅此处进行演示

于 2012-07-25T02:57:06.930 回答
1

至少对于 Google,访问令牌最终会过期。这就是androidAccountManager有这个invalidateAuthToken方法的原因——缓存的访问令牌已经过期,你需要告诉AccountManager你停止给你旧的,而是得到一个新的。这使得缓存令牌更加安全,因为令牌本身不会让您作为该用户永久访问。相反,当它有效时,它只是说“在最近的某个时候,这个令牌是由一个受信任的来源获得的”。

以下是我在使用令牌时发现的一些有用的东西。第一个是 Google 的 tokeninfo 端点。令牌本身只是 base64 编码的 JSON。这意味着它没有加密,因此您需要确保使用 HTTPS 进行通信。但是,这也意味着您可以检查令牌并更好地了解正在发生的事情。

https://www.googleapis.com/oauth2/v1/tokeninfo?id_token=

如果您的令牌是“abcdef”,您将导航到:

https://www.googleapis.com/oauth2/v1/tokeninfo?id_token=abcdef

谷歌会为你解包令牌。它是一个简单的 JSON 对象,其中包含一个“expires_in”字段,告诉您令牌仍然有效的秒数。在下面的视频中的 6:03,您可以看到解压后的令牌:

https://developers.google.com/events/io/sessions/383266187

该视频包含对 OAuth2 的全面概述,如果您要处理 OAuth 和令牌,则非常值得完整观看。演讲者还讨论了其他形式的 Oauth2 令牌,它们不是访问令牌,不会过期。

另一个有用的资源是 OAuth Playground。这让你可以做一些基本的事情,比如请求范围、组成请求和取回令牌。这个链接似乎偶尔可以工作,在 Chrome 上我必须安装 Oauth Playground 应用程序:

https://developers.google.com/oauthplayground/

这里是视频中的演讲者 Tim Bray 的教程,解释了如何使用访问令牌从 Android 应用程序与服务器进行通信。这对我很有用,因为我开始了解 Google API 控制台中的不同事物如何协同工作:

http://android-developers.blogspot.in/2013/01/verifying-back-end-calls-from-android.html

关于您问题的实际答案,我想说您永远不需要在服务器上缓存访问令牌。正如上面的验证来自 Android 的后端调用链接中所解释的,验证令牌几乎总是一个快速的静态调用,这意味着没有理由缓存令牌:

这些库可以缓存 Google 证书并仅在需要时刷新它们,因此验证(几乎总是)是一个快速的静态调用。

最后,您确实可以使用AccountManager来获取访问令牌。但是,Google 现在反而鼓励使用GoogleAuthUtilPlay Services 库中的类:

简而言之,与使用 OAuth2 请求 getAuthToken 和 getToken 有什么区别

请注意蒂姆·布雷(Tim Bray)的评论,同一个人再次来自上述链接,称他们正在为这GoogleAuthUtil条路线付出努力。但是请注意,这意味着您将仅限于 Google 身份验证。我相信AccountManager可以用来获取例如 Facebook 令牌,而不是GoogleAuthUtil.

于 2013-09-08T16:27:02.670 回答
1

它准确地描述了您想要的内容: https ://developers.google.com/identity/protocols/CrossClientAuth

于 2015-04-20T12:07:56.977 回答
0

当我们需要在非谷歌 OAuth 服务器上做类似的事情时,我们将令牌保存在网站上的数据库中。然后,该应用程序将在需要请求数据时使用 Web 服务来请求令牌。

用户可以在 Web 或应用程序上进行 OAuth 注册。它们共享相同的应用程序令牌,因此它们可以共享相同的访问令牌。注册后,我们会将访问和刷新令牌存储在数据库中,以供任何需要它的应用程序使用。

于 2012-07-25T01:00:43.230 回答