问个关于Nodejs中间件的问题

问个关于Nodejs中间件的问题

我使用了express 4 作为框架搭建了一个应用, 现在写了个认证相关的function(req, res, next),在单独的模块里面,并且exports了出来

在app.js里面 app.post(/.*$/, auth()); 直接这样调用是可以的

但是 app.use(auth()); 就不行了,请问这个是什么问题啊

或者可以给一个express 4 上自己写的中间件的例子吗?

8 回复

当然可以!你遇到的问题可能是因为你在使用 auth() 中间件时没有正确处理请求。在 Express 应用中,app.use 方法通常用于全局中间件,而 app.post 则用于特定路由的中间件。让我们来详细解释一下这个问题,并提供一个完整的示例。

问题分析

当你在 app.use(auth()) 中使用 auth() 时,Express 会尝试将 auth() 函数作为中间件链的一部分。然而,auth() 函数需要符合中间件的签名,即它应该是一个函数,接受 (req, res, next) 作为参数,并在内部调用 next() 来传递控制权。

示例代码

假设你的 auth.js 文件包含以下认证逻辑:

// auth.js
module.exports = function(req, res, next) {
    // 检查请求头中的认证信息
    if (req.headers.authorization === 'Bearer some-token') {
        // 如果认证通过,继续处理下一个中间件
        next();
    } else {
        // 认证失败,返回错误响应
        res.status(401).json({ message: 'Unauthorized' });
    }
};

接下来,在你的 app.js 文件中,你可以这样使用这个中间件:

// app.js
const express = require('express');
const auth = require('./auth');

const app = express();

// 使用全局中间件
app.use(auth());

// 特定路由的中间件
app.post('/login', (req, res) => {
    res.json({ message: 'Login successful' });
});

// 启动服务器
app.listen(3000, () => {
    console.log('Server is running on port 3000');
});

解释

  1. 认证中间件 (auth.js):

    • 这个中间件检查请求头中的 authorization 字段是否包含正确的令牌。
    • 如果认证通过,它调用 next(),将控制权传递给下一个中间件或路由处理器。
    • 如果认证失败,它会发送一个 401 Unauthorized 响应。
  2. 使用中间件 (app.js):

    • app.js 中,我们首先导入 auth 中间件。
    • 然后使用 app.use(auth()) 将其添加为全局中间件。
    • 我们还定义了一个 /login 路由,该路由仅在认证成功时才会被处理。

通过这种方式,你可以确保所有传入的请求都经过认证中间件的检查。如果认证失败,请求将不会到达任何其他路由处理器。


app.use(auth) 呢

auth被定义成了一个函数,这个函数返回一个新的函数,新函数是 function(req, res, next). 所以直接app.use(auth)是不行的

不确定是不是因为express4 抛弃了connect引起的,网上很多例子都是connect的

4没有用过

哦,还是谢谢啦

module.exports =function FUNNAME(arg1, arg2) {
  return function FUNNAME(req, res, next) {
  }
};

然后

app.use(FUNNAME());

调用

我的代码是这么写的 auth.js :

module.exports = function() {
    return function (req, res, next) {...};
}

app.js

...
auth = require("./middleware/auth"),
...
app.use(auth());

每次请求的时候,auth.js都没有运行。

我也试了不用匿名函数,结果是一样的

在Express 4中,app.use() 方法用于注册全局中间件,而 app.post() 方法则用于定义特定路由的处理程序。你提到的问题可能是由于 auth() 中间件被错误地调用或配置导致的。

解释

  1. app.post(/.*$/, auth()):

    • 这里你直接将 auth() 函数作为参数传递给了 app.post,这会在每次匹配到该路由时立即执行 auth() 函数。
  2. app.use(auth()):

    • 这里你想将 auth() 作为中间件添加到所有路由,但同样直接调用 auth() 会导致立即执行该函数,而不是将其注册为中间件。

正确的方式

你应该传递 auth 函数的引用,而不是立即执行它:

// app.js
const express = require('express');
const app = express();
const auth = require('./auth'); // 假设你的认证中间件在 auth.js 文件中

// 注册全局中间件
app.use(auth());

// 或者正确的方法是传递函数引用
app.use(auth);

// 定义路由
app.post('/login', (req, res) => {
    res.send('登录成功');
});

// 启动服务器
app.listen(3000, () => {
    console.log('服务器运行在 http://localhost:3000');
});

示例代码

假设你的 auth.js 文件内容如下:

module.exports = function auth(req, res, next) {
    // 示例认证逻辑
    if (req.headers['x-auth-token'] === 'secret-token') {
        next(); // 通过认证
    } else {
        res.status(401).send('未授权');
    }
};

总结

  • app.use() 中传递中间件函数的引用(如 app.use(auth))而不是立即执行它(如 app.use(auth()))。
  • 确保你的中间件函数遵循 (req, res, next) 的标准格式。

这样配置后,你的认证中间件应该能正常工作。

回到顶部