簡體   English   中英

在 Express 中對除特定路徑之外的所有路徑使用特定中間件

[英]Use specific middleware in Express for all paths except a specific one

我在 node.js 中使用帶有一些中間件功能的 Express 框架:

var app = express.createServer(options);
app.use(User.checkUser);

我可以使用帶有附加參數的.use function 來僅在特定路徑上使用此中間件:

app.use('/userdata', User.checkUser);

是否可以使用路徑變量,以便中間件用於除特定路徑(即根路徑)之外的所有路徑?

我在想這樣的事情:

app.use('!/', User.checkUser);

所以User.checkUser總是被調用,除了根路徑。

我會將 checkUser 中間件添加到我的所有路徑中,除了主頁。

app.get('/', routes.index);
app.get('/account', checkUser, routes.account);

要么

app.all('*', checkUser);
    
function checkUser(req, res, next) {
  if ( req.path == '/') return next();

  //authenticate user
  next();
}

您可以擴展它以在非身份驗證路徑數組中搜索 req.path:

function checkUser(req, res, next) {
  const nonSecurePaths = ['/', '/about', '/contact'];
  if (nonSecurePaths.includes(req.path)) return next();

  //authenticate user
  next();
}

不是直接將User.checkUser注冊為中間件,而是注冊一個新的輔助函數,比如checkUserFilter ,它會在每個 URL 上調用,但僅在給定的 URL 上將執行傳遞給 userFiled`。 例子:

var checkUserFilter = function(req, res, next) {
    if(req._parsedUrl.pathname === '/') {
        next();
    } else {
        User.checkUser(req, res, next);
    }
}

app.use(checkUserFilter);

理論上,您可以提供app.use表達式路徑。 例如類似的東西:

app.use(/^\/.+$/, checkUser);

在 express 3.0.0rc5 上嘗試過,但不起作用。

也許我們可以開一張新票並建議將此作為一項功能?

您也可以在每個路由上設置中間件。

// create application/x-www-form-urlencoded parser
var urlencodedParser = bodyParser.urlencoded({ extended: false })

// POST /login gets urlencoded bodies
app.post('/login', urlencodedParser, function (req, res) {
  if (!req.body) return res.sendStatus(400)
  res.send('welcome, ' + req.body.username)
})

采用

app.use(/^(\/.+|(?!\/).*)$/, function(req, resp, next){...

這會傳遞除 / 之外的任何 url。 除非,它對我有用。

一般來說

/^(\/path.+|(?!\/path).*)$/

(請參閱如何否定正則表達式中的特定單詞?

希望這可以幫助

使用這個名為express-unless 的

除非路徑是 index.html,否則要求對每個請求進行身份驗證。

app.use(requiresAuth.unless({
  path: [
    '/index.html',
    { url: '/', methods: ['GET', 'PUT']  }
  ]
}))

Path 它可以是字符串、正則表達式或其中任何一個的數組。 它也可以是一個對象數組,它是 URL 和方法密鑰對。 如果請求路徑或路徑與方法匹配,則中間件將不會運行。

這個圖書館肯定會幫助你。

@chovy 的解決方案是最好的。

另一種解決方案是:

我面臨着類似的問題。 所以我所做的是將“路由”文件中的功能拆分為不同的文件並分別導出。 同樣,我將它們分別導入到“服務器”文件中,並為各自的路由調用了中間件。 但是我不會大規模推薦這個,我有一個不到10條路線的小項目所以我不介意這樣做。 對於縮放,我會選擇chovy的方法。

解決方案是使用設置api和中間件的順序。 在你的情況下,它必須是這樣的。

 var app = express.createServer(options);
    
    // put every api that you want to not use checkUser here and before setting User.checkUser
    app.use("/", (req, res) => res.send("checkUser middleware is not called"));
    
    
    app.use(User.checkUser);
    
    // put every api that you want use checkUser
    app.use("/userdata", User.checkUser, (req, res) =>
      res.send("checkUser called!")
    );

這是一個完整的例子。

const express = require("express");
const app = express();
const port = 3002;

app.get("/", (req, res) => res.send("hi"));

app.use((req, res, next) => {
  console.log("check user");
  next();
});

app.get("/checkedAPI", (req, res) => res.send("checkUser called"));

app.listen(port, () => {
  console.log(`Server started at port ${port}`);
});

對我有用的是在初始化 for-all 檢查之前初始化你想要的單一路由,例如:

var app = express.createServer(options);

app.get('/', routes.index);

app.use(User.checkUser);

我個人的例子是這樣的並且有效:

const app = express();

...

app.use('/api/flow', flowLimiter, flowRouter);

app.use(csurf({
    cookie: false,
}));

...

因此csurf應用於除api/flow之外的所有路由 - 我在其中使用 sendBeacon,因此我無法將帶有標記的標頭應用於它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM