API 服务上线后,可能有被恶意调用或攻击的安全问题,尤其在不用鉴权就可以请求接口是更危险。目前攻击最常见的就是“短信轰炸机”,由于短信接口验证是App,网站检验用户手机号最真实的途径,使用短信验证码在提供便利的同时,也成了呗恶意攻击的对象,那么如何才能防止被恶意调用呢?
图形验证码
通常做法是将图形校验码和手机验证码进行绑定,用户输入手机号码,需要通过图形校验码才可以触发短信验证请求,这样能比较有效的防止恶意攻击。目前大部分应用都是采用这种方式,还有一种页面验证使用者是不是人类的交付方式也比较流行。
限定请求次数
在服务器端限定同 IP,同设备,同时间范围内的接口请求次数。比如同一号码重复发送的时间间隔,一般为 60
或 120
秒;设置每个 IP 每天最大的发送量;设置单个手机号每天的最大发送量。
比如在 Node.js 中,我们可以根据访客的 IP 地址限制他们每天只能调用请求短信验证 10 次。步骤如下:
步骤
- 获取访客的 IP 地址:在 Node.js 中,你可以使用 request、express 或者其他 HTTP 请求处理库来获取客户端的 IP 地址。例如,使用 request 库可以通过 request.ip 获取请求的 IP 地址。
- 存储 IP 地址和调用次数:你可以选择将 IP 地址和调用次数存储在内存中、数据库中或者其他持久化的存储方式中,以便后续进行查询和更新。例如,你可以使用 Map 对象来在内存中存储 IP 地址和调用次数的键值对。
- 设置调用次数限制:你可以设置每个 IP 地址的调用次数限制为 3 次。
- 检查 IP 地址和调用次数:在每次 API 请求到达时,你可以检查请求的 IP 地址是否存在于存储中,并且检查调用次数是否已经达到限制。如果未达到限制,则允许请求继续执行,并将调用次数加一;如果已经达到限制,则拒绝请求。
- 重置调用次数:在每天的特定时间(例如午夜),你可以定时重置存储中所有 IP 地址的调用次数,以便于新的一天重新开始计数。
代码实现
以下是一个简单的示例代码,展示了如何在 Node.js 中实现这个功能:
const express = require('express');
const app = express();
const port = 3000;
// 使用 Map 对象来存储 IP 地址和调用次数
const ipCallCountMap = new Map();
// 设置每天的调用次数限制为 10 次
const callLimit = 10;
// 获取客户端 IP 地址的中间件
app.use((req, res, next) => {
const clientIP = req.ip;
req.clientIP = clientIP;
next();
});
// API 路由
app.get('/api/sendSMS', (req, res) => {
const clientIP = req.clientIP;
// 检查 IP 地址是否存在于 Map 中
if (ipCallCountMap.has(clientIP)) {
const callCount = ipCallCountMap.get(clientIP);
// 检查调用次数是否达到限制
if (callCount >= callLimit) {
return res.status(429).json({ message: '调用次数超过限制' });
}
// 调用次数加一
ipCallCountMap.set(clientIP, callCount + 1);
} else {
// 如果 IP 地址不存在于 Map 中,初始化调用次数为 1
ipCallCountMap.set(clientIP, 1);
}
// 执行 API 逻辑
// ...
res.json({ message: 'API 调用成功' });
});
归属地是否一致
服务器端检查用户的 IP 所在地与手机号归属地是否匹配,如果不匹配则提示用户手动操作等。
服务器端代理请求
采用 https
https 需要秘钥交换,可以在一定程度上鉴别是否伪造 IP。
总结
本文用示例介绍了怎样根据访客的 IP 地址限制 API 调用次数,结合其他方式效果会更好
评论 (0)