让我们做一些解释,这样您就可以将这些点连接起来并进行更稳健的设计。最后有两(三)个地方存放它:
- 前端(您的 React 应用程序)
- 后端(您的服务器)
- 第三方服务
TL;DR:对注册用户使用非前端解决方案 + 速率限制,并妥善保护注册步骤(+验证码)。
- 前端
在前端存储任何东西都是一个坏主意,除非你完全确定你可以允许这些数据被暴露——常量、名称、图标,也许是一些 URL,所以你没有在 JS 中硬编码文件。
您的“编译”ReactJS(或任何其他框架)在构建时只是一个稍微损坏(缩小/转译/等)的 JavaScript,但要使其正常工作,客户端必须检索它并在浏览器中执行它。因此,在 ReactJS 应用程序启动之前,有 1+ 个请求下载 JavaScript 代码和应用程序的其他部分,具体取决于框架。
您可以在任何现代浏览器的网络监控选项卡中看到这些,或者简单地使用 Wireshark(除非加密,那么它有点烦人)或使用不太健全的浏览器的本地代理。
检索后,如果您自己不知道如何操作,您可以简单地尝试 Ctrl+F 或任何在线 deminifier/deobfuscator 并且您可以检索密钥。
检索时的含义
- 我可以冒充你提供颁发 API 密钥的服务
- 我可以通过频繁调用来锁定您的密钥/帐户(只是为了好玩或检索一些信息)
- 我可以使用您的网络进行抓取,而无需支付 API 密钥(如果已支付)或向此类服务供应商注册
- 如果它是每个请求的 API 密钥,并且有一些限制会导致您花钱,我可以通过服务运行一些愚蠢的
while (true) { callYourApi() } 让我匿名,只是为了让您花钱
根据 API 密钥和您打算解决此问题的严重程度,您可以将 .env 文件仅用于开发目的。尽管您永远不应该在前端存储 API 密钥,除非您明确必须将其存储在其中(例如地图),因为这通常是一个非常愚蠢的想法,并且允许任何人滥用它。
- 后端
如果正确配置和保护您的服务器,您的服务器会将密钥存储在无法通过简单的路径遍历(如果在文件中)或抓取(如果您尝试检索密钥以在前端部分执行)无法访问的任何地方。
因此,最明智和最安全的方法是通过自定义 API 或计划脚本收集数据来检索(任何服务的)数据,当您的前端被调用时,它们将能够以预渲染的形式检索或者已经获取,因此这种情况不需要密钥。
但是!这是有窍门的。如果您将自定义 API 设计为 /api/<key>=123 或 /api/<param> 并使用原始 API 的该参数在前端进行过滤,则攻击者不会关心 API 密钥,因为您已经免费创建了一个 API,并且使其公开且不安全。
所以GET /yourapi/<my data> 和 API 密钥是免费的,甚至不需要显示。
如何安全地做到这一点?两种简单的方法:
将数据预渲染为 HTML
然后您使用前端获取并仅显示 - 但这个可以被刮掉,如果更复杂,它会有点烦人,但就是这样。服务器端渲染听起来不错,但实际上不适用于这种情况。它应该主要用于使前端快速或模板化视图,但从不作为银弹解决方案出于安全目的(因为它不能那样工作)。
速率限制 + CORS + 账户管理
通过速率限制,您可以确保用户(最好只有在用户登录后才调用该 API)只能调用该 API,例如1 小时内 10 次,使用 CORS,您可以确保它只能由您的前端调用。
这也不是灵丹妙药,任何有一点脑子的人都可以简单地在本地抓取您的 API 从而绕过 CORS,但是如果您禁止从单个 IP 注册超过 1 个用户或如果您需要电话号码进行验证。并添加一些烦人的验证码,因此对某些人来说自动化是有问题的。
它仍然可能被攻击和滥用,但它痛苦,除非您允许多次使用相同的电话号码(或任何其他不太容易获得/需要努力获得的 ID),所以它会让最不称职的人离开……而其余的人,好吧,无论如何他们都会玩你的网站,所以如果你单独维护它,请进行适当的安全评估/强化你的服务器。
- 第三方
类似于 2.,但您不维护“低级”服务器部分,因为第三方正在为您管理它,您只需要指定调用它的条件。这适用于 Firebase 或 Supabase ,它们的行为类似于单独的后端,但可以有多个模块(对于 FB,1,2)。
因此,您将使用 Firebase functions(或其他替代方法),您将在其中拥有您的密钥,例如即使是硬编码,客户端(浏览器)也无法访问它,添加一个限制、cors,也许是一些用户注册限制,你就完成了。
注意:任何域、IP、地区、电话号码限制都可以绕过,所以不要依赖它们。这只是在将您的网站误用于与您预期不同的事情时需要付出努力的一种手段。
- 域:
curl http(s)://yourweb/path -H "Host: spoofed-domain"
- 地区或 IP:代理、VPN、Tor、I2P,只是别人的计算机/服务器 + ssh,一些随机 WiFi
- 电话号码:如果我想可以去当地商店买10个新鲜的