bugfix> node.js > 投稿

これが私のエクスプレスコードです:

       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をミドルウェアに送信するか、エクスプレスコードでIPをチェックして、IPがホワイトリストファイルにない場合にのみ使用するにはどうすればよいでしょうか。この問題は私を殺しています:/。

私の質問がばかげている場合は申し訳ありませんが、私は以前にエクスプレスで実際に働いたことはありません。

回答 1 件
  • あなたの主な問題はここにあるようです:

    }).use(rateLimiter(req))
    
    

    その前に何が来るかを正確に示すわけではありませんが、これが app.use() または router.use() 、次に、ミドルウェアをそれに渡す方法を次のように修正する必要があります。

    app.use(rateLimiter)
    
    

    これはミドルウェア機能を渡します rateLimiterapp.use() 後で呼び出すことができます。すべてのミドルウェアは3つの引数で呼び出されます (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;
    
    

    ここでそれについてさらに議論しますが、あなたのコードから、あなたはすでにそれを知っているように見えます。

あなたの答え