为啥我不能在我的快速路由中使用中间件?

Posted

技术标签:

【中文标题】为啥我不能在我的快速路由中使用中间件?【英文标题】:Why can't I use middleware in my express route?为什么我不能在我的快速路由中使用中间件? 【发布时间】:2020-04-22 04:34:59 【问题描述】:

我正在创建一个 API,所以我想添加一个用户系统并验证对 API 的访问。

这将是验证的中间件:

'use strict'

const jwt = require('jwt-simple');
const moment = require('moment');
const config = require('../settings/config');

function isAuth(req, res, next) 
    if (!req.headers.authotization) 
        return res.status(403).send(
            message: `No tiene autorizacion`
        )
    
    const token = req.headers.authotization.split(" ")[1];
    const payload = jwt.decode(token, user, config.token.secret_token);

    if (payload.exp <= moment().unix()) 
        return res.status(401).send(
            message: 'El token ha expirado'
        )

        req.user = payload.sub;
        next();

    


module.exports = isAuth;

虽然这是路线:

    'use strict'
    const express = require('express');
    const router = express.Router();
    const auth = require('../middlewares/auth');

    router.get('/', auth.isAuth, (req, res) => 
        res.status(200).send(
            message: `Tienes acceso`
        )
    )

另一方面,这是我的主要应用程序设置(app.js):

const express = require('express');
const bodyParser = require('body-parser');
const morgan = require('morgan');

const app = express();
const config = require('./config')

// Middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded( extended: false ));
app.use(morgan('dev'));

// Routes variables
const productRouter = require('../routes/product');
const privateRouter = require('../routes/private');

// Routes uses
app.use('/api/product', productRouter);
app.use('/private', privateRouter);

app.listen(config.app.port, err => 
    if (err) throw err;
    console.log(`Server listening on port $config.app.port`)
)

module.exports = app;

我收到此错误:

D:\api-rest-carlos-azaustre\node_modules\express\lib\router\route.js:202 抛出新的错误(味精); ^

错误:Route.get() 需要一个回调函数但得到了一个 [object 不明确的] 在路线。 [as get] (D:\api-rest-carlos-azaustre\node_modules\express\lib\router\route.js:202:15) 在 Function.proto 中。 [as get] (D:\api-rest-carlos-azaustre\node_modules\express\lib\router\index.js:510:19) 在对象。 (D:\api-rest-carlos-azaustre\routes\private.js:6:8) 在 Module._compile (internal/modules/cjs/loader.js:959:30) 在 Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10) 在 Module.load (internal/modules/cjs/loader.js:815:32) 在 Function.Module._load (internal/modules/cjs/loader.js:727:14) 在 Module.require (internal/modules/cjs/loader.js:852:19) 在需要(内部/模块/cjs/helpers.js:74:18) 在对象。 (D:\api-rest-carlos-azaustre\settings\app.js:15:23) 在 Module._compile (internal/modules/cjs/loader.js:959:30) 在 Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10) 在 Module.load (internal/modules/cjs/loader.js:815:32) 在 Function.Module._load (internal/modules/cjs/loader.js:727:14) 在 Module.require (internal/modules/cjs/loader.js:852:19) at require (internal/modules/cjs/helpers.js:74:18) [nodemon] 应用程序崩溃 - 在启动前等待文件更改...

有时会在错误的顶部添加这一行:

(node:3092) MaxListenersExceededWarning:检测到可能的 EventEmitter 内存泄漏。 11 个退出侦听器 > 添加到 [Bus]。使用emitter.setMaxListeners() 增加限制

阅读答案后,我编辑我的问题。我只放置了 auth 而不是 auth.isAuth,我收到以下错误:

D:\api-rest-carlos-azaustre\node_modules\express\lib\router\index.js:458 throw new TypeError('Router.use() 需要一个中间件函数但得到一个' + gettype(fn)) ^

TypeError: Router.use() 需要一个中间件函数,但得到了一个 目的 在 Function.use (D:\api-rest-carlos-azaustre\node_modules\express\lib\router\index.js:458:13) 在功能。 (D:\api-rest-carlos-azaustre\node_modules\express\lib\application.js:220:21) 在 Array.forEach () 在 Function.use (D:\api-rest-carlos-azaustre\node_modules\express\lib\application.js:217:7) 在对象。 (D:\api-rest-carlos-azaustre\settings\app.js:20:5) 在 Module._compile (internal/modules/cjs/loader.js:959:30) 在 Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10) 在 Module.load (internal/modules/cjs/loader.js:815:32) 在 Function.Module._load (internal/modules/cjs/loader.js:727:14) 在 Module.require (internal/modules/cjs/loader.js:852:19) 在需要(内部/模块/cjs/helpers.js:74:18) 在对象。 (D:\api-rest-carlos-azaustre\index.js:3:13) 在 Module._compile (internal/modules/cjs/loader.js:959:30) 在 Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10) 在 Module.load (internal/modules/cjs/loader.js:815:32) 在 Function.Module._load (internal/modules/cjs/loader.js:727:14) [nodemon] 应用程序崩溃 - 在启动前等待文件更改...

有人知道是什么原因吗?

【问题讨论】:

【参考方案1】:

module.exports = isAuth; 表示您导出函数,没有其他内容。这意味着当您执行const auth = require('../middlewares/auth'); 时,auth 是实际函数,而不是包含isAuth 作为属性的对象。

所以,router.get('/', auth, (req, res) =&gt; 应该有效,而不是无效的 auth.isAuth

在此处了解有关模块的更多信息:https://js.evie.dev/modules

【讨论】:

我在输入时遇到了一个新错误。我已将其添加到问题的末尾。 @DiesanRomero 我感觉问题不再与功能有关,而是与您的路由器有关。也许您在路由文件中缺少 module.exports,因为每个路由文件都需要导出路由器。这是关于如何正确形成它们的教程:scotch.io/tutorials/…【参考方案2】:

是的,您使用以下代码导出函数:module.exports = isAuth;

但是你这样调用它:auth.isAuth

假设你正在做类似const auth = require('./bin/auth.js'); 之类的事情

auth 将是函数本身——不会有 isAuth 属性。

所以你应该试试这个:

router.get('/', auth, (req, res) => 

你还没有发布你的整个代码,所以这只是一个最好的猜测。

【讨论】:

我在输入时遇到了一个新错误。我已将其添加到问题的末尾。请告诉我您需要更多信息,以便您可以帮助我。我会很高兴放置它并获得您的帮助。

以上是关于为啥我不能在我的快速路由中使用中间件?的主要内容,如果未能解决你的问题,请参考以下文章

在快速路由上应用 jwt 而不会引发错误

为啥我的 textarea 不能正好在中间居中?

Laravel 5.5 Entrust使用中间件授予路由组权限失败

如何从路由器访问应用程序级中间件?

访问rails中间件中的路由

如何在 NodeJS 中使用 JWT 令牌验证路由