node.js - 部署到heroku时express-rate-limit不起作用
问题描述
我有这个代码在 localhost 上工作(发送没有问题只有 express-rate-limit),但是当我将它部署/推送到我的 heroku 应用程序并执行发布请求时,它超过了最大限制,即 3。
const router = require('express').Router();
const nodemailer = require('nodemailer');
const rateLimit = require("express-rate-limit");
const apiLimit = rateLimit({
windowMs: 24 * 60 * 60 * 1000, // 24 hrs
max: 3, // limit each IP to 3 requests per windowMs
message: "Spam detected!"
});
router.route('/').post(apiLimit,(req, res) => {
const transport = nodemailer.createTransport({
service: 'gmail',
host : "smtp.gmail.com",
port : "465",
ssl : true,
auth: {
user: process.env.USER,
pass: process.env.PASS
}
});
const mailOptions = {
from: '',
to: '<myemail>',
subject: req.body.subject,
text: "FROM: "+ req.body.email + " MESSAGE: " + req.body.message
};
transport.sendMail(mailOptions, (err, info) => {
err ? res.json(res.status(400).json("Error " + err)) : res.json("Email sent.");
});
});
module.exports = router ;
在本地主机上服务有效,当我请求超过 3 倍时,它会返回检测到的垃圾邮件消息并且不再发送邮件。当我在 vscode 上使用 rest api 扩展时,这显示了。X-Ratelimit-Remaining: 2
如果我再做一些帖子请求,则不会改变。
HTTP/1.1 200 OK
Server: Cowboy
Connection: close
X-Powered-By: Express
Access-Control-Allow-Origin: *
X-Ratelimit-Limit: 3
X-Ratelimit-Remaining: 2
Date: Sun, 21 Jun 2020 03:09:11 GMT
X-Ratelimit-Reset: 1592793933
Content-Type: application/json; charset=utf-8
Content-Length: 13
Etag: W/"d-EBrE0f9LbjD0DZTwvOVLMa8Lqo8"
Via: 1.1 vegur
"Email sent."
解决方案
当您在 heroku 上运行 express-rate-limit 模块时,它似乎没有为客户端获取正确的 IP 地址?也许是因为 heroku 在您的服务器前使用了代理?
// Enable if you're behind a reverse proxy (Heroku, Bluemix, AWS ELB, Nginx, etc)
// see https://expressjs.com/en/guide/behind-proxies.html
// app.set('trust proxy', 1);
所以,看起来你可能需要:
app.set('trust proxy', 1);
这将导致使用X-Forwarded-For 标头中的地址列表填充req.ip
和req.ips
值,这可能是 express-rate-limiter 在代理后面运行时需要的。
推荐阅读
- c# - 如何在 Visual Studio 中编辑锁定的文件?
- python - Seaborn 传奇不显风采,只显色相
- html - 文本填充问题,CSS 动画
- google-sheets - 基于多张工作表中日期范围的带有 VLOOKUP 的 SUMIF
- android - 在 Android 中搜索 RecyclerView 项后,总是打开 RecyclerView 的第一项
- c - 在 FreeRTOS 任务中实现功能是一个好习惯吗?
- ios - 如何根据屏幕设计快速缩放按钮文本?
- python - 如何在 python 中的多个字符串中找到相似的内容?
- sql-server - 如何获取两个日期之间的日期('FromDate 和 ToDate'),如果我们在 Todate 中有空值,我们应该在 Todate 中更改为 getdate()?
- c# - 在 C# 中使用相同 UDP 端口的多个程序/实例