我正在开发一个主要通过应用访问的网站,并且我想使用OAuth2进行用户注册和认证。由于这是一个Android应用程序,因此我将开始使用Google的OAuth2,因为它在Android上提供了良好的UI界面。
Google表示"您可以选择使用Google的身份验证系统作为外包用户身份验证的一种方式。这可以消除创建、维护和保护用户名和密码存储的需要。" 这正是我想做的事情。然而当我浏览他们所有的示例等内容时,我只能找到关于网站或应用程序对Google服务进行用户认证的内容。
实际上,当我注册我的应用程序(“客户端”)时,Google的OAuth2有网站客户端和“已安装”客户端(即移动应用程序)的选项,但两者不能同时存在。我可以创建两个单独的客户端,但我读了OAuth2草案,我认为会有问题,现在我将解释一下。
以下是我设想的工作方式:
- 用户请求MyApp访问他的私人数据。
- 应用程序使用Android的
AccountManager
类请求Google API的访问令牌。 - Android向用户询问:“应用程序'MyApp'想要访问您在Google上的基本信息,是否允许?”
- 用户回答是。
AccountManager
使用存储在手机上的凭据连接到Google的OAuth2服务器,并请求访问令牌。- 访问令牌(遵循绿线)被返回。
AccountManager
将访问令牌返回给MyApp。- MyApp发送一个包含访问令牌的请求到MySite以获取用户的私人数据。
- MySite需要使用访问令牌验证用户。它使用此处描述中所述的方法与Google验证令牌 - “Google,这个令牌有效吗?”。
- 现在,我希望发生的是Google说:“是的,无论谁给了你这个令牌,他确实是那个用户。”,但我认为实际上会发生的事情(根据OAuth2草案和Google的文档)是它会说:“不行!该令牌仅对MyApp有效,而你是MySite。滚开!”。
AccountManager
UI而不是糟糕的弹出式WebView
。
编辑
Nikolay的临时答案(如果有效,我会回报!)是它实际上应该有效,Google的服务器不会关心访问令牌来自哪里。对我来说似乎有点不安全,但我会看看它是否有效!
更新
我使用Facebook而不是Google实现了这种模式,完全可行。 OAuth2服务器不关心访问令牌来自何处。至少Facebook不会,所以我认为Google也不会。
考虑到将访问令牌存储起来是非常不好的想法!但我们也不希望为了检查每个请求的身份验证而不得不访问Facebook/Google的服务器,因为这会减慢所有操作。最好的方法可能是为您的站点添加一个额外的身份验证cookie,当其访问令牌被验证时,您会分发该cookie,但更简单的方法就是像处理密码一样处理访问令牌,并存储其哈希值。您不需要加盐,因为访问令牌非常长。因此,上述步骤变成了以下类似形式:9. MySite需要使用访问令牌验证用户。首先,它会检查其缓存的哈希有效访问令牌。如果在那里找到令牌的哈希,则知道用户已通过身份验证。否则,它会按照在此处描述与Google进行检查 - “Google,这个令牌是否有效?”。
10. 如果Google表示访问令牌无效,则告诉用户离开。否则,Google会说“是的,这是一个有效的用户”,然后我们会检查我们的注册用户数据库。如果未找到该Google用户名(或者如果使用Facebook,则为Facebook ID),则可以创建新用户。然后,我们会缓存访问令牌的哈希值。