使用OAuth2为app *和*网站进行身份验证

时间:2012-07-24 13:28:46

标签: android oauth oauth-2.0 google-authentication

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

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草案,我认为会有一个问题,我现在将解释。

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

OAuth2 flow diagram

  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验证令牌as described here - “Google,此令牌是否有效?”。
  10. 现在,我想要发生的事情是Google说“是的,无论是谁给了你的确是那个用户。”但我认为实际上会发生这种情况(基于OAuth2草案和Google的文档)是它会说“没办法!该令牌仅对MyApp有效,而且你是我的网站.GTFO!”。
  11. 那我该怎么做呢?请不要说“使用OpenID”或“不要使用OAuth2”或其他类似无益的答案。哦,我真的想继续使用漂亮的AccountManager用户界面,而不是蹩脚的弹出窗口WebView

    修改

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

    更新

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

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

    9。 MySite需要使用访问令牌验证用户。首先,它检查哈希有效访问令牌的缓存。如果在那里找到令牌的散列,则它知道用户已经过身份验证。否则,它会与Google as described here一起检查Google,“Google,此令牌是否有效?”。

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

6 个答案:

答案 0 :(得分:5)

我刚刚将an answer发布到了类似的StackOverflow问题。

Google称之为Hybrid Apps并解释"Android app obtains offline access for Web back-end"

的方式

要点是,您必须将按摩的scope字符串传递给GoogleAuthUtil.getToken才能让它返回授权码(而不是OAuth2令牌)。根据{{​​3}},授权码可以从您的移动应用程序传递到您的服务器,并交换为OAuth2令牌和刷新令牌。

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

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

答案 1 :(得分:2)

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

上的流程

答案 2 :(得分:1)

您可能需要OpenID Connect,它使用OAuth令牌进行身份验证。至于AccountManager,当前的OAuth支持有点笨拙,新的Google Play Services即将发布'很快'应该会让这更好。请点击此处查看demo

答案 3 :(得分:1)

至少在Google上,访问令牌最终会过期。这就是为什么android AccountManager具有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

Google将为您解包令牌。它是一个简单的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现在改为鼓励在Play服务库中使用GoogleAuthUtil类:

In a nutshell what's the difference from using OAuth2 request getAuthToken and getToken

此处请注意Tim Bray的评论,同样是来自上述链接的人,说他们正在努力进入GoogleAuthUtil路线。但请注意,这意味着您将仅限于Google身份验证。我相信AccountManager可以用来获取Facebook令牌,而不是GoogleAuthUtil

答案 4 :(得分:1)

答案 5 :(得分:0)

当我们需要在非Google OAuth服务器上执行类似操作时,我们会将令牌保存在网站上的数据库中。然后,应用程序将在需要请求数据时使用Web服务请求令牌。

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