我有一个付费服务的 API 密钥。此 API 是从我网站上未经身份验证的页面调用的。我正在通过我的后端服务器将请求代理到付费服务。我还在 API 上添加了 CORS,以确保从我的站点调用它。
当用户通过浏览器访问时,上述保护措施有效。但是,可以从邮递员访问 API,这可能会导致我为付费服务支付巨额账单。确保仅从我的 JS 客户端调用 API 的最佳方法是什么?
我有一个付费服务的 API 密钥。此 API 是从我网站上未经身份验证的页面调用的。我正在通过我的后端服务器将请求代理到付费服务。我还在 API 上添加了 CORS,以确保从我的站点调用它。
当用户通过浏览器访问时,上述保护措施有效。但是,可以从邮递员访问 API,这可能会导致我为付费服务支付巨额账单。确保仅从我的 JS 客户端调用 API 的最佳方法是什么?
你不能。即使对于不是网站的东西,比如嵌入式设备,也总是可以打开硬件并检查固件,或者在极端情况下,打开芯片并用电子显微镜检查它们。对于网站来说,这完全是微不足道的。您的客户可以做的任何事情,任何其他客户也可以。这是互联网的去中心化性质以及网页的工作方式所固有的。
您可以采取一些措施来限制滥用行为,例如让您的服务器(而不是用户的浏览器)发出请求,并限制它代表您的用户执行请求的速率。身份验证可能会让您限制每个用户的请求和/或传递账单。但是,实际上控制用于与您的服务器(或第三方服务器)通信的客户端是不可能的。充其量,您可以混淆您的代码并尝试隐藏访问密钥,但最终,您无法完美地隐藏它。
实施身份验证并仅允许对经过身份验证的用户的请求进行代理。
否则你的服务会随着时间的推移而为人所知,其他人甚至公司可以使用它,而你将无法阻止它。
正如其他人所指出的,除非您启用身份验证,否则如果您的 API 暴露在互联网上,您无法完全阻止某人调用您的 API。
如果您想限制使用并使滥用者不方便调用您的 API,您可以在页面加载时发出令牌(CSRF 令牌)并要求该令牌出现在对 API 的请求中 - 这样 API 就可以调用了从启动页面加载的浏览器。
如果没有后端颁发的令牌,API 将无法直接调用,但当然有一些方法可以通过无头实现来自动化 Web 浏览器来解决这个问题。
您可以根据 IP 地址实施服务器端配额——同样有办法解决这个问题。
如果您的 API 具有重要价值,那么积极主动的攻击者总会找到解决方法。
但是,您是否有可能高估了价值?也许你可以采取一种迭代的方法:实施基本的速率限制,看看你有多少滥用,改进你的保护措施,或者当它产生超出你愿意接受的成本时禁用。
确保仅从我的 JS 客户端调用 API 的最佳方法是什么?
你没有。
您放入 JS 代码中的任何类型的DRM(例如 JS 客户端用来向服务器证明它是真实客户端的秘密 API 密钥)都不会长期保密,因为 javascript 和 HTTP 流量它生成的内容在现代浏览器中非常容易检查。
相反,您需要对用户进行身份验证和速率限制。您已经说过在用户拥有帐户之前调用此 API,但这里有一些关于速率限制的想法:
X-Forwarded-For
orForwarded
标头,然后对每个客户端 IP 地址应用速率限制。(尽管正确获取这些标头非常棘手,因此我不推荐基于 IP 的方法,尤其是如果您的服务器位于云环境中)我能给出的最后一条建议是不要让它变得有用;如果您直接代理第 3 方 API(即客户端可以设置任何请求内容并查看完整响应),那么是的,您已经构建了一个服务,人们可以在您的信用卡上使用第 3 方 API。不要那样做;至少部分由您的后端填充内容,或者在您的后端使用响应而不是将其发送到 JS 客户端,或其他东西。