限制Node.js Express中的API访问

7

我有一个Express服务器,其中包含几个API路由,就像这样:

server.post("/api/send-email", (req, res) => {

   });
});

您无需身份验证令牌即可访问API,但我只希望我的网站mydomain.com可以使用它。我已经尝试启用了这样的访问限制:

function restrictAccess(req, res, next) {
      if (req.headers['origin'] !== 'http://localhost:3000') {
        res.sendStatus(403);
      } else {
        next();
      }
    }

我随后将限制访问作为中间件加入到我的路由中。

当我使用Postman发送POST请求时,我就不能再访问API了,但是我只需更改来源标头即可再次访问。

我如何才能允许只有来自 mydomain.com 的请求?我已经在网上搜索了很长时间,但是找不到任何相关资料。这是否可能呢?


1
简而言之,你不能这样做。任何像Postman或脚本这样的工具都无法发送它想要的任何标头,因此标头本身对于限制访问仅限于您域中的网页是无用的。这就是网络的工作原理。限制访问通常需要用户登录或类似的东西(可能设置一个cookie供您检查),然后如果您发现您的API被滥用,您可以禁止/删除正在执行此操作的特定用户帐户。 - jfriend00
2个回答

12

如何只允许来自我的域名为mydomain.com的网页请求?

简而言之,你不能。 任何工具如 Postman 或任何脚本(比如 Node.js、PHP、Perl 等)都可以发送它想要的头或其他请求参数,因此仅使用头部来限制访问只属于你域名下的网页是无效的。

这就是网络的运作方式。

为了限制访问,一般需要用户登录或某些凭证(例如设置 cookie 并进行检查),如果发现 API 被滥用,可以禁止或删除正在滥用的特定用户账户。

还有其他技术可以使脚本或工具更难使用你的 API,但即使如此,它们也无法抵御一个想要付出努力的黑客。例如,你的服务器可以生成一个令牌并嵌入到你的网页中,每当你从网页中进行 API 请求时,都要包括网页上的令牌。然后,你的服务器会检查是否存在有效的令牌。确保令牌在合理的时间内过期,以防止黑客获取一个令牌并长时间使用。

一个决心的黑客仍然可以随时从你的网页中获取令牌,然后使用它,因此这只是一个障碍,而不能阻止一个决心的黑客。

唯一真正的解决方案,就像谷歌等公司使用的API一样,是要求每次API调用都需要某种凭据,并对API的滥用进行检测(例如速率限制、意外用途等),如果发现凭证被滥用,则撤销该凭证。这个凭证可以是开发者令牌(如某些谷歌API)或者可以是用户登录时的某种认证凭据(例如cookie)。
我曾经见过其他技巧的应用,其中一个API只有在先前来自网页的一系列请求后才能正常工作。这需要更多的实现和维护工作,但是如果您的网页通常会发出请求以获取网页,然后进行两个ajax调用,再请求五个图像,然后调用API,则可以让您的服务器跟踪来自特定浏览器的事件序列,只有当您看到预期的事件序列,看起来像是来自真实浏览器的网页请求时,才允许API调用。尽管如此,这仍然需要大量工作,并且仍然无法完全防止坚定不移的黑客使用类似Puppeteer的工具来自动化真实浏览器。

1
主要浏览器在发送请求时会携带原始头信息,不允许任何浏览器Javascript修改它。
非浏览器API客户端(例如Postman和其他工具)可以设置原始头信息以及其他头信息为任意值。非浏览器API客户端可以轻松伪造成浏览器的身份来欺骗你的API。
因此,安全提示:使用原始头信息的值来决定是否授权访问您的API并不能提供任何安全保障。
您确实需要某种令牌访问机制,特别是对于发送电子邮件的API。如果黑客找到了您的API,则您的托管服务将指责您发送垃圾邮件。
很抱歉,安全确实是一件麻烦的事情。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接