如何设计一个允许安全地跨域脚本编写的 javascript API?

发布于 2024-09-29 22:20:41 字数 387 浏览 1 评论 0原文

我喜欢使用 Google 地图 api 的方式,使用脚本包含,但我担心:

我的 api 是“半私有”的,也就是说,可以通过互联网访问,但应该允许安全传输数据和某种类型的数据。验证。数据应通过网络保持私密性,并且一个消费者不应该能够获取另一个消费者的数据。

如何使用 SSL 和某种身份验证来保证数据安全,同时仍然可以从纯 HTML 页面“水平”访问,而不需要服务器端代理?我需要管理密钥吗?如何将密钥发布到服务器而不被拦截?我可以使用 OpenId(或其他第三方身份验证)来对 api 用户进行身份验证,还是必须创建自己的身份验证机制?我查遍了 Google,但找不到安全设计和部署 API 的良好指南。

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

I like the way Google Maps' api is consumed, using a script include, but I'm worried:

My api is "semi-private", that is, accessible over the internet but should allow for secure transmission of data and some kind of authentication. The data should remain private over the wire, and one consumer shouldn't be able to get at another's data.

How can I use SSL and some kind of authentication to keep the data secure, but still accessible "horizontally" from a plain HTML page with no server-side proxy required? Do I need to manage keys? How will the keys be posted to the server without being intercepted? Can I use OpenId (or some other 3rd-party authentication) to authenticate api users, or do I have to create my own authentication mechanism? I've been all over Google and can't find a good guide to designing and deploying my API securely.

Right now I'm using REST and AJAX to consume them, but cross-domain calls are impossible. Any help or a pointer in the right direction would be much appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

冰之心 2024-10-06 22:20:41

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

我还会寻找现有技术,例如 Amazon 的 S3 服务。

所以:

  1. 用户提供秘密
  2. 客户端代码使用公钥来加密秘密
  3. JavaScript 附加一个 script 标签,其中包含 URL
  4. 服务器处理脚本请求,解密秘密,检查它,然后发回相关信息回复。

您很可能需要两个周期,因为否则对服务器的请求可能会通过中间人攻击而被重复使用。这将是:

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

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

I'd probably use a dynamically-generated script tag with an SSL URL that included a key in the query string that was public-key encrypted. The server would use the private key to decrypt the query string parameter and return script that included the relevant information (or didn't, if the key was invalid). Or something along those lines. But I'll admit that I haven't actually had to do it in practice.

I'd also look for prior art, like Amazon's S3 service.

So:

  1. User provides secret
  2. Client-side code uses public key to encrypt the secret
  3. JavaScript appends a script tag that includes the URL
  4. Server handles the script request, decrypts the secret, checks it, and sends back the relevant response.

You may well need two cycles, because otherwise the request to the server could be re-used via a man-in-the-middle attack. That would be:

  1. JavaScript appends a script tag that requests a unique key (probably with some confounding information, like the source IP and some random further key)
  2. Server responds with a one-time key tied to that IP
  3. User provides secret
  4. Client-side code uses public key to encrypt the secret, including the unique key from #1
  5. JavaScript appends a script tag that includes the URL
  6. Server handles the script request, decrypts the secret, checks it, and sends back the relevant response.
  7. The response could well be encrypted (to some degree) using the random key included in #1

None of which I've actually done. (Or have I? BWAa-ha-ha-ha...) FWIW.

莳間冲淡了誓言ζ 2024-10-06 22:20:41

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

====== ==

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

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

OAuth might help with this situation by having the user login to the 3rd-party application and allowing your application to access the 3rd-party on their behalf by using a request token when you make xhr requests. http://oauth.net/documentation/getting-started/

========

The reason for using a server-side proxy boils down to the Same-origin policy built into web browsers: http://en.wikipedia.org/wiki/Same_origin_policy

Essentially the browser only allows requests to be made to the address in which the page comes from (e.g. facebook.com can only make requests to facebook.com URIs). A server-side proxy solves this issue by making requests to servers outside the current origin. Server-side proxies are also the best practice for making requests like this.

情绪失控 2024-10-06 22:20:41

查看开源 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,并使用它对您的站点进行安全调用以执行您想要执行的任何操作。

Check out the opensource javascript Forge project. It provides a javascript TLS implementation that allows secure cross-domain xhr requests. It might be of use to you:

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

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

https://github.com/digitalbazaar/forge

One potential solution:

  1. Set up an Apache server to run your site.
  2. Get an SSL certificate for your site.
  3. Install the apache mod that comes with Forge to setup a cross-domain policy that allows other sites to access yours.
  4. Host Forge's TLS implementation on your site along with your site's certificate in PEM format.
  5. Tell other sites to include the javascript from your site and use it to make secure calls to your site to do whatever it is you want to.
小梨窩很甜 2024-10-06 22:20:41
  1. (第 3 方)页面使用 OAUTH 或类似的方式来验证用户身份并从您的服务器获取令牌。
  2. 页面通过 SSL 从您的服务器加载 IFRAME,并传递令牌以进行身份​​验证。
  3. IFRAME 可以通过 SSL 安全地与您的服务器通信。
  4. 使用 easyXDM 或类似的东西在 IFRAME 和第 3 方页面之间进行通信,使用您创建的一些有限的类似 RPC 或类似套接字的 API。

或者,如果您确实不信任第三方 - 在 iframe 内进行身份验证(那么不需要 oauth,只需使用纯 html 表单)并使用 easyXDM 传达外部页面需要了解的有关用户的任何信息。

  1. (3rd party) Page uses OAUTH or something similar to authenticate the user and get a token from your server.
  2. Page loads an IFRAME from your server via SSL passing the token along for authentication.
  3. The IFRAME can communicate securely to your server via SSL
  4. Use easyXDM or something similar to communicate between the IFRAME and the 3rd party page, using some limited RPC-like or socket-like API you create.

Or if you really don't trust the third party - do your authentication inside the iframe (no need for oauth then, just use a plain html form) and communicate anything the outer page needs to know about the user using easyXDM.

暗地喜欢 2024-10-06 22:20:41

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

两台服务器可以互相通信吗?怎么样:

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

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

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

  4. Regular.com 使用 session_id 查找 otp 密码:密钥,并解密 otp 加密消息“blabla”。

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

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

  7. 完成页面加载。

从那里,您可以对

https://secure.com 进行类似 jsonp 的调用/getscript.js?query=dataname&verifiedtoken=(verified_sessions_cookie_value)

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

这有点像三向握手,秘密在于服务器必须能够直接相互通信以传递密钥。您不必为两台服务器使用相同的 session_id,我只是将其用作寻找访问 syn/ack otp 密码的方法的简单参考点。密码必须对公众完全隐藏。

Not too sure of what the question is exactly, I take it you're attempting to do a jsonp-like call to [https://secure.com] in order to process/display data on [http://regular.com]?

Can the two servers talk to each other? How about something like this:

  1. User logs in on [https://secure.com]

  2. Upon authentication, secure.com generates an token (lets call it syntoken) and passes it directly to regular.com (server-to-server), maybe like a session_id, some arbitrary message, and an otp cipher (lets call it syncipher).

  3. Broswer receives a session_id cookie, and Secure.com then redirects the browser to http://regular.com/setcookieandredirect?session_id=blabla&otpencryptedsynmessage=blabla

  4. Regular.com looks up otp cipher using session_id as a key, and decrypts otpencryptedmessage "blabla."

  5. If decrypted message matches the original message in the syntoken, we can verify user is logged in [regular.com] and regular.com generates another token (lets call it acktoken, lolz) and passes it directly to [secure.com], consisting of session_id, some arbitrary ack message, and a different otp cipher (lets call it ackcipher).

  6. Regular.com then sends the browser a cookie consisting of otpencryptedackmessage (let's name this cookie "verified_session").

  7. Finish loading the page.

From there, you can do jsonp-like calls to

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

where secure.com/getscript.js will take the verifiedtoken, lookup the ackcipher based on the original cookie session_id sent by [secure.com] as the key, and decrypt the otpencrypedackmessage. If the decrypted message matches the ack message, render the script file.

It's kinda like a 3-way handshake. The secret sauce is that the servers have to be able to talk to each other directly to pass secret keys discretely. You don't have to use the same session_id for both servers, I was just using that as an easy point of reference to find a way to access the syn/ack otp ciphers. The ciphers must be completely hidden from public.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文