我一直在Google和SO上搜索几个小时,但没有找到像我现在面对的那样挑战的人,所以这里有:
我们有一个数据库,我们花了很多钱和精力来维护。来自数据库的数据可通过REST-API公开获得。 我们还有一个公共的JavaScript网络应用程序,它使用这个API,我们销售给大约30-40个客户。因为API中的数据对我们来说非常有价值 尝试保护它,以便没有人可以从中获取内容并制作他们自己的数据库副本。我们也不希望任何人使用我们的API构建服务 未经我们同意。与此同时,我们需要http://www.example.com/theApp,http://www.example2.com/theApp,http://www.example3.com/theApp等网络应用 能够访问API。 没有涉及用户。每个人都可以访问http://www.example.com/theApp并获得该网站的完整功能。 API也是只读的,所以我们不担心 任何人试图污染我们的数据。
javascript Web应用程序是使用react.js与node.js服务器构建的。当然,SSL将用于服务器和客户端之间的所有通信。
我认为不起作用的事情
可能有效的事情(或者至少是解决方案的一部分):
由于这是我们正在努力实现的一件非常复杂的事情,所以我开始相信这可能是不可能的,如果有人对如何做有任何建议,我将不胜感激。 如果有充分的理由,“不要这样做”是一个非常好的答案。我更倾向于这里的概念解决方案,但如果有人想要在软件上具体化,我们就有了 带有node.js,Nginx和PHP的Linux环境。
答案 0 :(得分:1)
如果您不想对用户进行身份验证(您不希望他们登录),则无法确定谁在使用您的API,或者哪些请求来自哪个用户。发出API请求所需的所有信息都已经在javascript客户端中,任何人都可以创建另一个客户端,或者对API提出有效请求,您甚至无法判断请求是来自新客户端还是来自新客户端与之前的请求一样(想要下载数据库的人可以在许多客户端计算机上分发下载)。
丹尼尔的答案可能就是你能以这种方式达到目标的最接近的答案。如果您发出令牌,那么至少可以撤销令牌。但是,您仍然无法阻止攻击者请求新的攻击者。我在阅读你的问题后的想法是,javascript网络应用程序可能不是你想要的。你说你的客户比较少,而你根本不想登录。这会是一个给他们像桌面/移动客户端的选择吗?它可能仍然是Javascript包装在某种容器中,但对于每个客户端,您可以编译一个包含自己的密钥。一个明显的风险是他们仍然可以提取密钥,但这种方式不是任何人都可以拥有一个密钥的客户端,事实上,泄露的密钥将与其合法所有者相关联,并且您可以有合同条款来涵盖该方案(禁止逆向工程等)。您还可以监视和控制数据库的大量下载并撤消违规密钥,或实施其他安全措施,如限制对某些客户端IP地址的密钥访问(如果您的方案中可能的话)。
当然,这种风险在您的情况下可能是可接受的,也可能是不可接受的,只是一个想法。显然,从客户端获取密钥很容易,重点不是每个人都有客户从中获取有效密钥。一种更好的方法可能是仅将密钥作为客户端的许可文件单独分发,它基本上是相同的,但没有"硬编码密钥的概念" (我认为他们在这种情况下并不是真的)。这将使您的生活更轻松,因为您不需要在撤销密钥的情况下分发完整的客户端,只需要新的许可证文件。
这当然是身份验证,但在某种程度上可能会更加用户友好,因为用户不需要做任何事情。
对于该数量的客户端的另一个想法是客户端证书。对于任何想要使用API的客户,您都会提供客户端证书。任何人都可以下载您的Web应用程序,但客户端证书可用于验证API的调用者。它与上面的键相同,但处于不同的级别。撤销和发布一个新的更难(并且可能更昂贵),你仍然无法阻止下载整个数据库,但同样,你会有证据证明是谁做的,并且可以撤销他们的密钥和封面这在您的客户合同中。
答案 1 :(得分:0)
混淆是所描述方案中的唯一选择。您想使攻击者很难对您的Web客户端进行反向工程。
如果要求客户端进行复杂的计算以发出成功的API请求,则攻击者必须对该工程进行反向工程并将其复制到另一个应用程序中。
一些有用的东西:
以上任何一项都不会阻止有足够动机的攻击者。
答案 2 :(得分:-1)
在我看来,最安全的解决方案是oauth2
,或者如果您想要更灵活oauth
。
它允许生成和终止访问令牌。您可以计算任何令牌占用的来源数量,如果有人试图下载您的所有数据,则会使其无效。
很棒的教程: