我正在开发一个主要通过应用程序访问的网站,我想使用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草案,我认为会有一个问题,我现在将解释。
以下是我设想的工作方式:
AccountManager
类来请求Google API的访问令牌。AccountManager
使用手机上存储的凭据连接到Google的OAuth2服务器,并要求提供访问令牌。AccountManager
将访问令牌返回给MyApp。那我该怎么做呢?请不要说“使用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),我们可以创建新用户。然后我们缓存访问令牌的散列值。
答案 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注册。他们共享相同的应用程序令牌,因此他们可以共享相同的访问令牌。注册后,我们会在数据库中存储访问权限和刷新令牌,以便从需要的任何应用程序中使用。