如何将OAuth与单页面应用程序集成?

Gol*_*den 44 oauth single-sign-on oauth-2.0 single-page-application

使用OAuth时(2)我需要在我的应用程序中使用重定向端点,一旦我通过身份验证,OAuth提供服务就可以重定向到该端点.

如何在单页面应用程序中处理此问题?当然,重定向到OAuth提供服务并不好,甚至可能无法重定向.

我知道OAuth还支持基于用户名/密码的令牌生成.这与AJAX调用完美配合,但要求我的单页应用程序要求输入用户名和密码.

你通常如何处理这个?

Jos*_*llo 48

大多数情况下,即使对于SPA,重定向也是可以的,因为用户不喜欢将他们的X服务凭证放在除X之外的任何其他网站上.另一种方法是使用一个小弹出窗口,您可以查看Discourse的作用.恕我直言,重定向比弹出更好.

谷歌有些提供程序支持资源所有者流,这就是您所说的发送用户名和密码,但这并不好.这些是我看到的问题:

  1. 向您网站中的用户询问Google凭据对某些用户来说是不可取的.
  2. 资源所有者流也需要client_secret,这是你不能放在客户端javascript中的东西.如果您从服务器端应用程序实例化资源所有者流并且您的应用程序与用户不在同一地理区域,则用户将收到警告"嘿,有人试图使用您的来自印度的凭据访问".

OAuth描述了一个称为隐式流的客户端流程.使用此流程,您不需要在服务器端进行任何交互,也不需要client_secret.OAuth提供程序使用"#access_token = xx"重定向到您的应用程序.它被称为隐式,因为您不需要为每个访问令牌交换授权代码,您可以直接获得access_token.

Google实施隐式流程,请检查:将OAuth2用于客户端应用.

如果你想使用隐式流与一些不支持它的提供者(如Github),你可以使用像Auth0这样的身份验证代理.

免责声明:我为Auth0工作.


tne*_*tne 21

JoséF.Romaniello 所说的是正确的.但是,你的问题是广泛的,因此我认为任何提供的结论只是这一点上的一般性.

申请状态

例如,不知道你的应用程序状态的复杂程度,在你想要让您的用户登录的时候,没有人能知道,如果使用重定向甚至实际可言.考虑到您可能愿意让用户在他的工作流程/应用程序使用中很晚才登录,在应用程序保持状态的情况下,您确实不希望序列化并保存.更别说编写代码来重建它.

注意:您将看到很多建议,只需在网络上忽略这一点.这是因为许多人将其应用程序的大多数状态存储在服务器端会话存储中,而在其(瘦)客户端上存储的很少.有时是错误的,有时它确实有意义 - 如果你选择忽略它,请确保它适合你.如果您正在开发一个胖客户端,它通常不会.

弹出对话框

我意识到弹出窗口因为所有的误用而在网络上有不好的代表,但是必须考虑好的用途.在这种情况下,它们与其他类型的系统中的可信对话框完全相同(想想Windows UAC,fd.o polkit等).这些接口都可以识别并使用其底层平台的功能,以确保它们不会被欺骗,并且输入或显示不能被非特权应用程序拦截.确切的并行是浏览器chrome,特别是证书挂锁不能被欺骗,并且单源策略阻止应用程序访问弹出窗口的DOM.对话框(弹出窗口)和应用程序之间的交互可以使用跨文档消息传递其他技术发生.

这可能是最佳方式,至少在浏览器以某种方式标准化权限授权之前,如果他们这样做的话.即使这样,某些资源提供者的授权过程也可能不适合标准化实践,因此我们今天看到的灵活的自定义对话可能是必要的.

同窗过渡

考虑到这一点,弹出窗口背后的美学确实是主观的.将来,浏览器可能会提供API以允许在现有窗口上加载文档而不卸载现有文档,然后允许新文档卸载并还原以前的文档."隐藏"应用程序是继续运行还是被冻结(类似于虚拟化技术如何冻结进程)是另一个争论.这将允许与弹出窗口相同的过程.我知道没有提议做到这一点.

注意:您可以通过某种方式模拟此操作,使所有应用程序状态都可以轻松序列化,并具有在本地存储(或远程服务器)中存储和恢复它的过程.然后,您可以使用旧式重定向.正如开头所暗示的那样,这可能会非常干扰应用程序代码.

标签

另一种选择当然是打开一个新选项卡,与弹出窗口完全相同,然后以相同的方式关闭它.

从非特权应用程序获取用户凭据

当然,只有当您的用户信任您不足以将凭据发送到您的服务器时(或者他们不希望它们最终结束的任何地方),它才能工作.如果您开源代码并进行确定性构建/最小化,理论上用户可以审核或让某人审核代码,然后自动验证您没有篡改运行时版本 - 从而赢得他们的信任.在网上执行此操作的工具是不存在的AFAIK.

话虽这么说,有时你想在你控制/权威/品牌下使用OAuth与身份提供者.在这种情况下,整个讨论都没有实际意义 - 用户已经信任您.

结论

最后,它归结为(1)客户端的厚度,以及(2)您希望UX的样子.