使用OAuth2为应用*和*网站进行身份validation

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

Google表示: “您可以select使用Google的身份validation系统作为为您的应用程序外包用户身份validation的方式,这可以消除创build,维护和保护用户名和密码存储的需要。 这是我想要做的。 但是,当我浏览所有的示例和其他内容时,我只能find有关网站应用程序对Google服务进行身份validation的信息。

事实上,当我使用Google的OAuth2注册我的应用程序(“客户端”)时,网站客户端和“已安装”客户端(即移动应用程序)可以select,但不能同时使用。 我可以创build两个独立的客户端,但是我阅读了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需要使用访问令牌来validation用户。 它按照这里描述的那样validation令牌,用Google – “Google,这个令牌是否有效?”。
  10. 现在,我想要发生的是,Google说:“是的,谁给了你的就是这个用户”,但是我认为实际发生的事情(基于OAuth2草案和Google的文档)是:这个标记只对MyApp有效,而你是MySite。GTFO!“。

那我该怎么做呢? 并请不要说“使用OpenID”或“不要使用OAuth2”或其他类似的无益的答案。 哦,我真的想继续使用好的AccountManager UI而不是蹩脚的popupWebView

编辑

暂时的答案(我会报告,如果它的工作!)从尼古拉是它应该实际上工作,谷歌的服务器将不关心访问令牌来自哪里。 似乎有点不安全,但我会看看它是否有效!

更新

我用Facebook而不是Google实现了这个模式,它完全可以工作。 OAuth2服务器不关心访问令牌来自哪里。 至lessFacebook的不,所以我认为谷歌也不会。

鉴于此,存储访问令牌是一个非常糟糕的主意! 但是我们也不希望打开Facebook / Google的服务器来检查每个请求的身份validation,因为它会减慢一切。 可能最好的办法是为您的站点添加一个额外的身份validationcookie,当您的访问令牌经过validation时,您可以发出一个额外的身份validationCookie,但更简单的方法就是将访问令牌视为密码并存储其密码。 因为访问令牌真的很长,所以你不需要去加盐。 所以上面的步骤就像这样:

9. MySite需要使用访问令牌来validation用户。 首先它检查散列的有效访问令牌的caching。 如果发现令牌的散列,它知道用户被authentication。 否则,按照Google的说明与Google进行核对 – “Google,这个标记是否有效?”。

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

您可能需要OpenID Connect,它使用OAuth令牌进行身份validation。 对于AccountManager ,目前的OAuth支持有点不好,即将推出的新版Google Play服务希望能够让这个更好。 看到这里的演示 。

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

谷歌称这个混合应用程序,并解释了“Android应用程序如何获得Web后端的离线访问” 。

其要点是,您必须将按摩scopestring传递到GoogleAuthUtil.getToken才能使其返回授权码(而不是OAuth2令牌)。 该授权码可以从您的移动应用程序传递到您的服务器,并根据此示意图交换OAuth2令牌和刷新令牌。

scope参数需要如下所示:

 oauth2:server:client_id:<your_server_client_it>:api_scope:<scope_url_1> <scope_url_2> ... 

您可以在其他任何地方使用由移动应用程序检索的访问令牌。 Drive SDK有一个很好和简单的介绍,通过https://developers.google.com/drive/quickstart-android

至less在Google中,访问令牌最终会过期。 这就是为什么Android的AccountManagerinvalidateAuthToken方法 – caching的访问令牌已经过期,你需要告诉AccountManager停止给你旧的,而是得到一个新的。 这使得caching令牌更为安全,因为令牌本身并不会以该用户的身份给予您永久的访问权限。 相反,当它有效时,它只是说“在最近的某个时刻,这个标记是由一个可靠的来源获得的”。

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

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

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

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

Google会为你解开令牌。 这是一个简单的JSON对象,其中包含一个“expires_in”字段,告诉您令牌仍然有效的秒数。 在下面的video6:03,你可以看到解压缩的令牌:

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

该video包含对OAuth2的全面概述,如果您要处理OAuth和令牌,则完全值得关注。 演讲者还讨论了其他forms的Oauth2令牌,这些令牌不是访问令牌,不会过期。

另一个有用的资源是OAuth游乐场。 这可以让你做一些基本的事情,比如请求范围,补充请求以及获取令牌。 这个链接似乎偶尔工作,在Chrome上,我不得不安装Oauth Playground应用程序:

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

以下是video演讲者Tim Bray的一个教程,解释了如何使用访问令牌从Android应用程序与服务器进行通信。 这对我非常有用,因为我开始了解Google API控制台中的不同function是如何协同工作的:

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

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

这些库可以cachingGoogle证书,只在需要时刷新它们,所以validation(几乎总是)一个快速的静态调用。

最后,您确实可以使用AccountManager获取访问令牌。 但是,Google现在反而鼓励在Play服务库中使用GoogleAuthUtil类:

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

在这里,请注意Tim Bray的评论,同样的人又从上面的链接,他们正在努力到GoogleAuthUtil路线。 但请注意,这意味着您只能使用Google身份validation。 我相信AccountManager可以用来取代Facebook令牌,而不是GoogleAuthUtil

它描述了你想要的: https : //developers.google.com/identity/protocols/CrossClientAuth

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

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