在单页应用程序中如何进行Dropbox身份验证而不打开新窗口?

8
我有一个单页应用程序,与Dropbox和LinkedIn等其他服务集成。例如,Dropbox具有出色的API,并通过在另一个窗口中打开Dropbox的身份验证链接来获得身份验证功能。一旦用户进行身份验证,我会要求他们关闭该新窗口以返回我的应用程序。
显然,这不是最佳选择,因为它会将用户带离我的应用程序,而且在平板电脑上更加繁琐。
如何在应用程序内完成身份验证,例如使用轻箱或模态表单?
请注意,集成本身发生在服务器端而不是客户端。目前,Dropbox身份验证页面具有回调页面,向我的服务器发出信号表示身份验证成功,我将其存储在数据库中的用户表中以备将来使用。
注意:悬赏评论应该是:高度期望提供代码示例,但不是必需的。

你能澄清一下你的应用程序在哪里运行吗?也就是说,这是一个用户在自己的浏览器中访问的Web应用程序还是本地应用程序/哪个平台等? - Greg
这是一个基于Backbone和相关技术构建的Web应用程序,也将通过PhoneGap在移动设备上提供下载。我可能可以在PhoneGap中使用Dropbox SDK,因此这个问题集中在浏览器内的Web应用程序上。 - Tony Abou-Assaleh
谢谢您的快速澄清!我已经发布了我的答案,如果我有误解,请告诉我 :-) - Greg
3个回答

11

你提出的建议是破坏安全模型,这是不应该被允许的。用户应该能够查看真实页面的URL以进行验证。想象一下,当你使用Paypal进行付款时,你可能会在输入重要数据之前检查你是否在paypal.com上,对吧?所有其他应用程序都适用于同样的规则。这是一种非常丑陋的流程,但目前业界想出的最好解决方案。

理想的流程是将用户重定向到第三方网站或应用程序,用户登录并授权,然后重定向回您的网站或应用程序。原生应用程序有一个切换到另一个原生应用程序的优势,因此流程会更少一些丑陋。

可以做到您想要的结果的解决方法是,应用程序要求用户提供第三方服务的用户名和密码,然后在幕后自己完成身份验证过程。这很可能会使用户不再使用您的应用程序,而且非常危险。我不建议这样做。


2
我进行了一个快速测试,结果发现Dropbox在响应头中发送X-Frame-Options,这使得Andreas描述的iframe方法在这种情况下无法使用。不确定ChildBrowser是否适用于手机应用程序的情况,但答案对于一般的Web应用程序是正确的。谢谢Alex。 - Tony Abou-Assaleh

4
你可以在网页中的 iframe 中加载 授权端点。但是,请注意某些浏览器对于在 iFrame 中发送给登录提供程序的 cookie 存在限制。通常情况下(Safari、iOS),您只有读取 cookie 的权限,如果会话 cookie 已经在提供程序中设置,则足以满足要求。
在回调页面上,即在从 Dropbox 身份验证后返回的页面上,您需要调用一个 JavaScript 函数来触发父页面的事件,表示身份验证已完成。
window.parent.AppController.authenticationComplete();

父级页面可以移除 iframe,然后继续进行身份验证。
authenticationCompleted = function() {
     // [snipp]
     $("iframe#loginwrapper").remove();
}

由于潜在的cookie问题,我建议在提供主HTML页面之前从服务器端执行所有身份验证步骤。这样,您就可以确保应用程序不会被加载两次。这是许多身份验证/身份中间件软件解决方案的典型行为。
当你提到“应用程序”时,不清楚你是指纯WebApp,还是通过使用Phonegap等框架在混合应用程序中具有可控性。使用Phonegap或类似工具,您可以在应用程序内部加载浏览器 - 在这种情况下,ChildBrowser没有相同的cookie限制。我最近编写了一个关于如何在iOS上使用Phonegap和Childbrowser的教程。
请注意,此教程是关于使用OAuth 2.0,与OAuth 1.0有所不同。OAuth 2.0 Guide for Phonegap using ChildBrowser and JSO

是的,在 Web 应用程序中有效的所有内容,在 PhoneGap 中也有效。 - Andreas Åkre Solberg
无论您的应用程序如何实现,当用户与Dropbox身份验证登录页面交互时,仍可能遇到cookie限制问题,可能会受到设置cookie的限制而导致错误。 - Andreas Åkre Solberg
我明白了。在不先实施整个项目的情况下,有没有一种更确切地了解这是否会是一个问题的方法? - Tony Abou-Assaleh
2
顺便提一下,同样的方法不仅适用于IFrame,还适用于独立子窗口。您的auth-callback可以向认证窗口发送一些JavaScript,该JavaScript首先调用应用程序窗口上的函数以告知认证成功,然后自动关闭认证窗口。此方法仍会为认证打开新的窗口/选项卡,但会使用户立即返回应用程序,而无需进行额外的单击。如果IFrame无法正常工作,则可能是一种替代方案。 - Oliver
他的观点在网页上是完全正确的!但是在原生应用程序中,用户是否能看到URL并不重要,因为它无论如何都无法信任它。 - Andreas Åkre Solberg
显示剩余3条评论

0

如果您的应用程序是Web应用程序,简化流程的最佳方法是将当前页面重定向(例如,如何在JavaScript / jQuery中重定向到另一个网页?)到Dropbox上的/authorize页面,并使用oauth_callback将其重定向到您的应用程序上的页面,指示已完成该过程。

这样,流程就是:

  1. (在您的应用程序上)用户单击按钮以启动OAuth流程
  2. (您的应用程序重定向到Dropbox授权页面)用户授权应用程序
  3. (Dropbox根据oauth_callback重定向到您的应用程序)应用程序获取访问令牌并准备使用集成

所有这些都发生在单个页面内,而无需关闭/打开额外的窗口。


感谢您的回答。您提出的解决方案非常适合将所有内容保留在一个窗口中,但它并不是真正的“单页应用程序”。单页应用程序会在后台加载大量数据、JS和HTML,以提供无需刷新的体验,即单击链接不会触发完整页面加载,而仅会对相关部分进行页面内更改。使用您的方法,当用户通过回调返回应用程序时,整个应用程序数据都需要重新加载,这就破坏了拥有单页Web应用程序的好处。 - Tony Abou-Assaleh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接