我需要为除少数 IP 之外的所有人应用中间件,但我无法在路由之外获取 req 和 res,我该如何应用它?
I need to apply middleware for everyone excepte a few IPs, but I can't get req and res outside of route, how could I apply it?
这是我的快递代码:
res.setHeader('Content-Type', 'application/json');
if (req.query.uuid) {
db.getPlayerByUUID(req.query.uuid, (data) => {
res.send(data)
})
} else if (req.query.name != null) {
db.getPlayerByName(req.query.name, (data) => {
res.send(data)
})
}
}).use(rateLimiter(req))
这是我的中间件:
const fs = require('fs')
const rateLimit = require('express-rate-limit')
const whitelist = JSON.parse(fs.readFileSync("./config/whitelist.json").toString())
const blacklist = JSON.parse(fs.readFileSync("./config/whitelist.json").toString())
const config = JSON.parse(fs.readFileSync("./config/config.json").toString())
const rateLimiter = (req) => {
const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
if (blacklist.indexOf(ip) <= -1) {
console.log(ip)
if (whitelist.indexOf(ip) <= -1) {
const rateLimiter = rateLimit({
windowMs: 60 * 1000,
max: config.webserver.limit,
message: {error: 'You have exceeded the requests in 1 min limit! Please try again soon.'},
headers: true,
})
}
} else {
res.status(403).send('You cannot use this service!');
}
}
module.exports = {
rateLimiter
}
那么我如何将我的 IP 发送到我的中间件或检查我的 express 代码中的 IP 并仅当 IP 不在我的白名单文件中时才使用它?这个问题让我很烦:/.
抱歉,如果我的问题很愚蠢,我以前从未真正使用过 express。
看来你的主要问题在这里:
}).use(rateLimiter(req))
您没有准确显示之前的内容,但如果这是 app.use()
或 router.use()
,那么您需要修复将中间件传递给它的方式,如下所示:
app.use(rateLimiter)
这会将中间件函数 rateLimiter
传递给 app.use()
以便稍后调用。所有中间件都使用三个参数调用 (req, res, next)
因此,您需要修改中间件以匹配它。
然后,您需要在中间件中适当地使用这些参数来实现您的目标。这是一个可能的实现,应该向您展示它是如何工作的。
// create middleware from your rate limiting package to later conditionally apply
const limiter = rateLimit({
windowMs: 60 * 1000,
max: config.webserver.limit,
message: {error: 'You have exceeded the requests in 1 min limit! Please try again soon.'},
headers: true,
})
const rateLimiter = (req, res, next) => {
const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
// implement your ip address limiting here
// you should have one of three outcomes
// 1. You call next() to allow the routing to continue for this request
// 2. You call next(someError) to abort routing and fall-through to
// your Express error handler
// 3. You send a response using something like res.status(xxx).send(),
// thus ending the request
// block this request if the IP address is on the blacklist
if (blacklist.indexOf(ip) >= 0) {
res.status(403).send('You cannot use this service!');
return;
}
// if the IP address is on the whitelist, then let it go
if (whitelist.indexOf(ip) >= 0) {
// continue routing
next();
return;
}
// apply rate limiter middleware
limiter(req, res, next);
}
app.use(rateLimiter);
这会在此处创建一个名为 limiter
的中间件和一个名为 rateLimiter
的中间件。 rateLimiter
中间件将根据 app.use(rateLimiter)
在每个请求传入请求上调用。然后,在里面它会检查黑名单和白名单。如果它在黑名单上,它将请求短路并以 403 结束它。如果它在白名单上,它将继续路由并让后续路由处理程序处理它。如果它不在任何一个列表中,那么它将通过手动调用速率限制中间件并将传递给您的中间件的 (req, res, next)
传递给它来有条件地对其应用速率限制。
对您提出的问题的其他评论:
I need to apply middleware for everyone except a few IPs, but I can't get req and res outside of route, how could I apply it?
req
和 res
仅存在于处理给定传入请求的过程中。因此,一旦请求结束,与该请求关联的那些对象将被垃圾收集并且不再可用。即使你设法把它们塞到某个地方,那也不会对你有多大好处,因为与 res
对象关联的套接字已经完成并且可能已关闭,你无法继续向任何人发送更多数据。
因此,除了处理路由或中间件之外,您无法访问 req
和 res
。这就是它们可用和有用的地方。
So how could I either send my IP to my middleware or check the IP in my express code and use it only if the IP is not in my whitelist file? This issue is killing me
传入请求的 IP 地址在 req
对象中可用。您的中间件可以访问它。
通常的做法是:
const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
对此进行了更多讨论 here,但从您的代码来看,您似乎已经知道了。
这是我的快递代码:
res.setHeader('Content-Type', 'application/json');
if (req.query.uuid) {
db.getPlayerByUUID(req.query.uuid, (data) => {
res.send(data)
})
} else if (req.query.name != null) {
db.getPlayerByName(req.query.name, (data) => {
res.send(data)
})
}
}).use(rateLimiter(req))
这是我的中间件:
const fs = require('fs')
const rateLimit = require('express-rate-limit')
const whitelist = JSON.parse(fs.readFileSync("./config/whitelist.json").toString())
const blacklist = JSON.parse(fs.readFileSync("./config/whitelist.json").toString())
const config = JSON.parse(fs.readFileSync("./config/config.json").toString())
const rateLimiter = (req) => {
const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
if (blacklist.indexOf(ip) <= -1) {
console.log(ip)
if (whitelist.indexOf(ip) <= -1) {
const rateLimiter = rateLimit({
windowMs: 60 * 1000,
max: config.webserver.limit,
message: {error: 'You have exceeded the requests in 1 min limit! Please try again soon.'},
headers: true,
})
}
} else {
res.status(403).send('You cannot use this service!');
}
}
module.exports = {
rateLimiter
}
那么我如何将我的 IP 发送到我的中间件或检查我的 express 代码中的 IP 并仅当 IP 不在我的白名单文件中时才使用它?这个问题让我很烦:/.
抱歉,如果我的问题很愚蠢,我以前从未真正使用过 express。
看来你的主要问题在这里:
}).use(rateLimiter(req))
您没有准确显示之前的内容,但如果这是 app.use()
或 router.use()
,那么您需要修复将中间件传递给它的方式,如下所示:
app.use(rateLimiter)
这会将中间件函数 rateLimiter
传递给 app.use()
以便稍后调用。所有中间件都使用三个参数调用 (req, res, next)
因此,您需要修改中间件以匹配它。
然后,您需要在中间件中适当地使用这些参数来实现您的目标。这是一个可能的实现,应该向您展示它是如何工作的。
// create middleware from your rate limiting package to later conditionally apply
const limiter = rateLimit({
windowMs: 60 * 1000,
max: config.webserver.limit,
message: {error: 'You have exceeded the requests in 1 min limit! Please try again soon.'},
headers: true,
})
const rateLimiter = (req, res, next) => {
const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
// implement your ip address limiting here
// you should have one of three outcomes
// 1. You call next() to allow the routing to continue for this request
// 2. You call next(someError) to abort routing and fall-through to
// your Express error handler
// 3. You send a response using something like res.status(xxx).send(),
// thus ending the request
// block this request if the IP address is on the blacklist
if (blacklist.indexOf(ip) >= 0) {
res.status(403).send('You cannot use this service!');
return;
}
// if the IP address is on the whitelist, then let it go
if (whitelist.indexOf(ip) >= 0) {
// continue routing
next();
return;
}
// apply rate limiter middleware
limiter(req, res, next);
}
app.use(rateLimiter);
这会在此处创建一个名为 limiter
的中间件和一个名为 rateLimiter
的中间件。 rateLimiter
中间件将根据 app.use(rateLimiter)
在每个请求传入请求上调用。然后,在里面它会检查黑名单和白名单。如果它在黑名单上,它将请求短路并以 403 结束它。如果它在白名单上,它将继续路由并让后续路由处理程序处理它。如果它不在任何一个列表中,那么它将通过手动调用速率限制中间件并将传递给您的中间件的 (req, res, next)
传递给它来有条件地对其应用速率限制。
对您提出的问题的其他评论:
I need to apply middleware for everyone except a few IPs, but I can't get req and res outside of route, how could I apply it?
req
和 res
仅存在于处理给定传入请求的过程中。因此,一旦请求结束,与该请求关联的那些对象将被垃圾收集并且不再可用。即使你设法把它们塞到某个地方,那也不会对你有多大好处,因为与 res
对象关联的套接字已经完成并且可能已关闭,你无法继续向任何人发送更多数据。
因此,除了处理路由或中间件之外,您无法访问 req
和 res
。这就是它们可用和有用的地方。
So how could I either send my IP to my middleware or check the IP in my express code and use it only if the IP is not in my whitelist file? This issue is killing me
传入请求的 IP 地址在 req
对象中可用。您的中间件可以访问它。
通常的做法是:
const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
对此进行了更多讨论 here,但从您的代码来看,您似乎已经知道了。