如何使用 node.js/express 中止请求?
Posted
技术标签:
【中文标题】如何使用 node.js/express 中止请求?【英文标题】:How to abort a request with node.js/express? 【发布时间】:2016-11-30 12:52:32 【问题描述】:如果满足某个条件(登录尝试次数过多),我想阻止对给定 IP 地址的所有进一步请求。为了实现这一点,我目前正在查看 Node.js
和 express
文档,但我找不到合适的方法来中止请求。到目前为止,我所能想到的只是一个普通的res.status(403).end()
,然而,它会在 HTTP 级别发送一个完整的答案。
因此,我想中止 TCP 级别的连接。我的想法是这样的:
server.on('connection', (sock) => if (shouldBlock(...) sock.destroy(); );
这会按我想要的方式工作,还是这是不好的做法?它似乎有效,但我很好奇这是否会对其他(非阻塞)请求造成任何泄漏、问题或副作用?
【问题讨论】:
您可以在您的用户架构中拥有 ip_address、login_attempts、status。一旦特定 ip 的 login_attempts 超过您设置的值,只需将状态设为“已阻止”,然后每当用户尝试登录时,您只需向他发送带有标题的正确消息。这会不会解决您的问题而不是中止连接,因为如果流量更多,中止连接可能会很昂贵。 【参考方案1】:如果您想对被阻止的 IP 感到恼火,那么您可以通过以下方式延迟您的响应:
setTimeout(() => res.status(403).end(), 10000);
但我不会这样做有两个原因。首先,与立即响应相比,这对您的服务器来说需要更多的工作。其次,您可能会阻塞和浪费您和客户端之间的某些代理服务器的资源 - 包括您自己的反向代理等。
出于同样的原因,我也不建议静默断开连接,这也可能会给您自己的服务器带来一些问题。
您可以改为在路由表中添加规则,以在来自特定 IP 地址的连接到达您的节点服务器之前将其删除。请记住,如果连接到达您的 Node 应用程序,那么即使它们被您的应用程序丢弃,它们仍然会敲击您的应用程序并浪费您的资源。
例如在 Linux 上,您可以像这样阻止某个 IP:
iptables -A INPUT -s 1.2.3.4 -j DROP
其中 1.2.3.4 是您要阻止的 IP 地址。
在 Node 中你可以使用node-iptables。
我当然不建议将被阻止的 IP 存储在数据库中并在每个请求上检查它,因为它对您的服务器来说比一开始就为这些请求提供更多的工作。如果您为此创建数据库,请确保它是 Redis 或其他一些快速的内存数据库。
您还需要考虑的是,很多时候人们都在 NAT 之后,因此例如整个公司或学校都可以使用相同的 IP 地址。因为一个孩子进行了太多登录尝试而默默地断开整个学校的连接,这会使您的服务在该学校的其他任何人看来都已损坏。此类功能可能会被用于您的服务器,以故意为某些人禁用它。
【讨论】:
感谢您的回复。我知道基于代理/防火墙的阻塞会更好(我在这里问了一个类似的问题:***.com/questions/40761850/…),但现在我有一个具体的要求,即我将在我的应用程序中阻塞请求。我考虑过放弃 TCP 连接会留下最小的风险,因为它可以例如不要进一步利用超出 TCP 级别的任何东西。以上是关于如何使用 node.js/express 中止请求?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 node.js Express 发送 POST 请求?
每次在 Node.js (Express.js) 中发出 API 请求之前,如何简化 Fetching Auth token?
Node.js + Express 接口请求(GETPOSTPUT)事例
如何发送 POST 请求以响应 node.js Express?