从JavaScript到后端的API调用:无需服务器端代码即可确保合法性

从JavaScript到后端的API调用:无需服务器端代码即可确保合法性,javascript,api,security,widget,Javascript,Api,Security,Widget,我想创建一个Javascript小部件,我的用户可以把它放在他们的网站上。 这个小部件能够创建音频,这反过来会让我的用户花钱。 为了便于说明,假设每次互联网上的任何人(即我用户的用户)加载放置在我用户站点上的小部件时,我都会向我的用户收取1美元的费用 这个小部件是一个围绕HTML音频播放器的Javascript代码。每次加载JS代码时,它都会向我的后端API发出一个请求,一旦收到来自后端API的响应,就会构建播放器 图表: 我担心的是非我的用户恶意使用。 假设有人在我的一个用户的网站上找到了小

我想创建一个Javascript小部件,我的用户可以把它放在他们的网站上。 这个小部件能够创建音频,这反过来会让我的用户花钱。

为了便于说明,假设每次互联网上的任何人(即我用户的用户)加载放置在我用户站点上的小部件时,我都会向我的用户收取1美元的费用

这个小部件是一个围绕HTML音频播放器的Javascript代码。每次加载JS代码时,它都会向我的后端API发出一个请求,一旦收到来自后端API的响应,就会构建播放器

图表:

我担心的是非我的用户恶意使用。 假设有人在我的一个用户的网站上找到了小部件的源代码,并将其放在了自己的网站上。因此,他们会使用我的服务,但不会为此付费。相反,我的实际用户将为此付费(假设我使用公共API密钥作为区分用户的方法)

通常,这是通过让服务器端库负责任何可能花钱的使用来防止的。例如,我使用Pusher作为WebSocket IaaS,每当我想发布消息时,我都必须在服务器端使用他们的PHPSDK,使用私有和公共API密钥

在我的用例中,必须没有服务器端库

问题:如何确保我收到的API请求是合法的?

我考虑使用放置小部件的主机名作为合法性度量。在小部件设置期间,我可以要求用户将某些(子)域列入白名单,并拒绝所有不符合条件的请求,但这很容易被自定义本地域或定制请求欺骗


我理解这可能是不可能的。

您所问的似乎与客户端加密主题密切相关。在大多数情况下,答案是否定的,这是不可能的。然而,在这种情况下,可以按照以下思路实现一些东西。如果你能让你的客户安装一个插件(你将构建),你可以在完成后加密你的JS代码,并让你的服务器提供这个加密文件。通常情况下,这是不够的,如果你发送一个加密文件,客户端需要有一种方法来解密它。这将要求您还提供一个未加密的JS文件来执行解码,但通过提供未加密的解码器,您可以撤销加密主JS文件所获得的任何安全性(解密文件可以很容易地用于对加密方法进行反向工程/只需直接为非预期用户运行)。现在,这些API用户(以及通过服务器-客户机连接之外的方式与他们通信的能力)就在这里派上了用场。如果您构建了一个解密插件,并将其提供给API用户(您可以为每个用户颁发一个唯一的解密密钥,但如果没有服务器访问实现唯一的用户密钥将非常困难/不可能),那么该插件就可以在他们的浏览器中解密您提供的文件,本质上保证只有您提供“密钥”的用户才能访问您的软件。然而,这种方法有几个警告。这意味着你足够信任你的用户,他们不会分发插件(无论如何分发插件都会违背他们的意愿,因为如果有人冒充他们,可能会导致更高的费用)。这种方法可能还有一些其他的安全问题,但是,我现在想不起来。如果你有任何想法,我会编辑这篇文章并添加它们。

你所问的似乎与客户端加密的主题密切相关。在大多数情况下,答案是否定的,这是不可能的。然而,在这种情况下,可以按照以下思路实现一些东西。如果你能让你的客户安装一个插件(你将构建),你可以在完成后加密你的JS代码,并让你的服务器提供这个加密文件。通常情况下,这是不够的,如果你发送一个加密文件,客户端需要有一种方法来解密它。这将要求您还提供一个未加密的JS文件来执行解码,但通过提供未加密的解码器,您可以撤销加密主JS文件所获得的任何安全性(解密文件可以很容易地用于对加密方法进行反向工程/只需直接为非预期用户运行)。现在,这些API用户(以及通过服务器-客户机连接之外的方式与他们通信的能力)就在这里派上了用场。如果您构建了一个解密插件,并将其提供给API用户(您可以为每个用户颁发一个唯一的解密密钥,但如果没有服务器访问实现唯一的用户密钥将非常困难/不可能),那么该插件就可以在他们的浏览器中解密您提供的文件,本质上保证只有您提供“密钥”的用户才能访问您的软件。然而,这种方法有几个警告。这意味着你足够信任你的用户,他们不会分发插件(无论如何分发插件都会违背他们的意愿,因为如果有人冒充他们,可能会导致更高的费用)。这种方法可能还有一些其他的安全问题,但是,我现在想不起来。如果有任何想法,我将编辑这篇文章并添加它们。

如何将以下参数从JavaScript小部件发送到API后端:

  • 公开API密钥(例如bbbe3b259f881cfc796f468619eb9d)
  • 当前URL(例如
    https://example.com/articles/chiang-mai-thailand-january-2016-june-2016
我将使用API键作为区分我的用户和当前URL的一种方式