繁体   English   中英

如何设计一个允许跨域脚本安全的JavaScript API?

[英]How can I design a javascript API that allows for cross-domain scripting securely?

我喜欢谷歌地图的api消费方式,使用脚本包括,但我很担心:

我的api是“半私有的”,即可通过互联网访问,但应允许安全传输数据和某种身份验证。 数据应该通过网络保持私有,并且一个消费者不应该能够获得另一个数据。

我如何使用SSL和某种身份验证来保证数据安全,但仍然可以从纯HTML页面“水平”访问,而不需要服务器端代理? 我需要管理密钥吗? 如何在不截获的情况下将密钥发布到服务器? 我可以使用OpenId(或其他一些第三方身份验证)来验证api用户,还是必须创建自己的身份验证机制? 我一直在谷歌,无法找到安全设计和部署我的API的好指南。

现在我正在使用REST和AJAX来使用它们,但是跨域调用是不可能的。 任何帮助或正确方向的指针将非常感激。

我可能会使用动态生成的脚本标记,其中包含SSL URL,该URL包含公钥加密的查询字符串中的密钥。 服务器将使用私钥来解密查询字符串参数并返回包含相关信息的脚本(如果密钥无效,则返回脚本)。 或类似的规定。 但我承认在实践中我实际上并没有这么做。

我也会寻找现有技术,比如亚马逊的S3服务。

所以:

  1. 用户提供秘密
  2. 客户端代码使用公钥来加密秘密
  3. JavaScript附加包含URL的script标记
  4. 服务器处理脚本请求,解密秘密,检查它,并发回相关的响应。

您可能需要两个周期,因为否则可以通过中间人攻击重新使用对服务器的请求。 那将是:

  1. JavaScript附加一个script标记,请求一个唯一的密钥(可能包含一些混淆信息,如源IP和一些随机的其他密钥)
  2. 服务器使用与该IP绑定的一次性密钥进行响应
  3. 用户提供秘密
  4. 客户端代码使用公钥来加密秘密,包括来自#1的唯一密钥
  5. JavaScript附加包含URL的script标记
  6. 服务器处理脚本请求,解密秘密,检查它,并发回相关的响应。
  7. 可以使用#1中包含的随机密钥对响应进行加密(在某种程度上)

我实际上没有做过。 (或者我?BWAa-ha-ha-ha ......) FWIW。

OAuth可以通过让用户登录第三方应用程序并允许您的应用程序在您发出xhr请求时使用请求令牌代表他们访问第三方来帮助解决这种情况。 http://oauth.net/documentation/getting-started/

========

使用服务器端代理的原因归结为Web浏览器中内置的同源策略: http//en.wikipedia.org/wiki/Same_origin_policy

基本上,浏览器只允许对页面来自的地址发出请求(例如,facebook.com只能向facebook.com URI发出请求)。 服务器端代理通过向当前源外的服务器发出请求来解决此问题。 服务器端代理也是发出这样的请求的最佳实践。

查看opensource javascript Forge项目。 它提供了一个javascript TLS实现,允许安全的跨域xhr请求。 它可能对您有用:

http://digitalbazaar.com/2010/07/20/javascript-tls-1/

http://digitalbazaar.com/2010/07/20/javascript-tls-2/

https://github.com/digitalbazaar/forge

一个潜在的解决方

  1. 设置Apache服务器以运行您的站点。
  2. 获取您网站的SSL证书。
  3. 安装Forge附带的apache mod以设置允许其他站点访问您的跨域策略。
  4. Host Forge在您网站上的TLS实施以及您的网站PEM格式的证书。
  5. 告诉其他网站包含您网站上的javascript并使用它来安全地呼叫您的网站,以便做您想做的任何事情。
  1. (第三方)页面使用OAUTH或类似的东西来验证用户并从您的服务器获取令牌。
  2. 页面通过SSL从服务器加载IFRAME,并将令牌传递给身份验证。
  3. IFRAME可以通过SSL安全地与您的服务器通信
  4. 使用easyXDM或类似的东西在IFRAME和第三方页面之间进行通信,使用您创建的一些类似RPC或类似套接字的API。

或者,如果你真的不信任第三方 - 在iframe中进行身份验证(不需要oauth,只需使用简单的html表单),并使用easyXDM通知外部页面需要了解的有关用户的任何信息。

不太确定问题究竟是什么,我认为你试图对[https://secure.com]进行类似jsonp的调用,以便在[http://regular.com]上处理/显示数据]?

两台服务器可以互相通话吗? 这样的事情怎么样:

  1. 用户登录[https://secure.com]

  2. 经过身份验证,secure.com会生成一个令牌(让我们称之为syntoken)并将其直接传递给regular.com(服务器到服务器),可能像session_id,一些任意消息和一个otp密码(让我们称之为同步) 。

  3. Broswer收到session_id cookie,然后Secure.com将浏览器重定向到http://regular.com/setcookieandredirect?session_id=blabla&otpencryptedsynmessage=blabla

  4. Regular.com使用session_id作为密钥查找otp密码,并解密otpencryptedmessage“blabla”。

  5. 如果解密的消息与syntoken中的原始消息匹配,我们可以验证用户是否登录[regular.com]并且regular.com生成另一个令牌(让我们称之为acktoken,lolz)并将其直接传递给[secure.com],包括session_id,一些任意ack消息和一个不同的otp密码(让我们称之为ackcipher)。

  6. 然后,Regular.com向浏览器发送一个由otpencryptedackmessage组成的cookie(让我们将此cookie命名为“verified_session”)。

  7. 完成加载页面。

从那里,你可以做类似jsonp的调用

https://secure.com/getscript.js?query=dataname&verifiedtoken=(verified_sessions_cookie_value

其中secure.com/getscript.js将采用verifiedtoken,根据[secure.com]发送的原始cookie session_id作为密钥查找ackcipher,并解密otpencrypedackmessage。 如果解密的消息与ack消息匹配,则呈现脚本文件。

这有点像三次握手。 秘诀是服务器必须能够直接相互通信以离散地传递密钥。 您不必为两个服务器使用相同的session_id,我只是使用它作为一个简单的参考点来找到访问syn / ack otp密码的方法。 密码必须完全隐藏在公众面前。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM