首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TypeError: Router.use()需要一个中间件函数,但是有一个未定义的包含两个中间件的函数

TypeError: Router.use()需要一个中间件函数,但是有一个未定义的包含两个中间件的函数
EN

Stack Overflow用户
提问于 2021-07-07 17:40:28
回答 1查看 189关注 0票数 1

我必须在我的ts节点应用上运行测试,在运行测试时我遇到了这个问题,因为这个应用程序的路由必须通过两个中间件,一个是授权,另一个是有效请求,我有这个配置路由。

代码语言:javascript
复制
const router = express.Router();
router.use('/cars', requiredAuthorization, requiredHeadersValidator, cars);


router.use('/healthcheck', healthcheck());

export default router;

在运行测试时,我得到了这个错误:

代码语言:javascript
复制
  ● Test suite failed to run

TypeError: Router.use() requires a middleware function but got a undefined

   8 | const cars = require('../routes/cars');
   9 |
> 10 | router.use('/cars', requiredAuthorization, requiredHeadersValidator, cars);
     |        ^
  11 | router.use('/healthcheck', healthcheck());
  12 |
  13 | export default router;

  at Function.use (node_modules/express/lib/router/index.js:458:13)
  at Object.<anonymous> (src/web-server/routes/index.ts:10:8)
  at Object.<anonymous> (src/web-server/index.ts:7:1)
  at Object.<anonymous> (src/web-server/middlewares/required-authorization.ts:3:1)
  at Object.<anonymous> (src/web-server/middlewares/__tests__/required-authorization.test.ts:4:1)

我在这里和其他部分尝试过几乎所有的答案,但它们似乎都没有帮助(在每一个路由文件中都有一个导出默认路由器线)。

更新

这些中间件是:

代码语言:javascript
复制
import { Request, Response, NextFunction } from 'express';
import { StatusCodes } from 'http-status-codes';
import { autho } from '../index';

const requiredAuthorization = async (req: Request, res: Response, next: NextFunction) => {

  if (!req.headers.authorization) {
    return res.status(StatusCodes.FORBIDDEN)
    .json({
      errors: [{
        status: StatusCodes.FORBIDDEN, detail: 'Unauthorized'
      }]
    });
  }

  let idToken;
  if (req.headers.authorization && req.headers.authorization.startsWith('Bearer ')) {
    idToken = req.headers.authorization.split('Bearer ')[1];
  } else {
    return res.status(StatusCodes.FORBIDDEN)
    .json({
      errors: [{
        status: StatusCodes.FORBIDDEN, detail: 'Unauthorized'
      }]
    });
  }

  try {
    await autho.auth().verifyIdToken(idToken);
    next();
    return;
  } catch (error) {
    return res.status(StatusCodes.FORBIDDEN)
    .json({
      errors: [{
        status: StatusCodes.FORBIDDEN, detail: 'Unauthorized'
      }]
    });
  }

};

export default requiredAuthorization;

以及:

代码语言:javascript
复制
import { Request, Response, NextFunction } from 'express';
import { ReasonPhrases, StatusCodes } from 'http-status-codes';

const requiredHeadersValidator = (req: Request, res: Response, next: NextFunction) => {
  if (req.header('Content-Type') !== 'application/vnd.api+json') {
    return res.status(StatusCodes.UNSUPPORTED_MEDIA_TYPE)
      .json({
        errors: [{
          status: StatusCodes.UNSUPPORTED_MEDIA_TYPE, detail: ReasonPhrases.UNSUPPORTED_MEDIA_TYPE
        }]
      });
  }

  if (req.header('Accept') !== 'application/vnd.api+json') {
    return res.status(StatusCodes.NOT_ACCEPTABLE)
      .json({
        errors: [{
          status: StatusCodes.NOT_ACCEPTABLE, detail: ReasonPhrases.NOT_ACCEPTABLE
        }]
      });
  }

  next();
};

export default requiredHeadersValidator;

进口:

代码语言:javascript
复制
import * as express from 'express';
import * as healthcheck from 'express-healthcheck';
import requiredAuthorization from '../middlewares/required-authorization';
import requiredHeadersValidator from '../middlewares/required-headers-validator';
import cars from './cars';

cars.ts文件:

代码语言:javascript
复制
import * as express from 'express';
import { BrandController } from '../controllers/brand-controller';
import { ModelController } from '../controllers/model-controller';
import { VehicleController } from '../controllers/vehicle-controller';

const router = express.Router();

// brands
router.get('/brands', BrandController.findAll);
router.get('/brands/:id', BrandController.findById);
router.get('/brands/:id/models', BrandController.findModelsByBrandId);
router.post('/brands', BrandController.create);
router.patch('/brands/:id', BrandController.updateBrandById);
router.delete('/brands/:id', BrandController.deleteBrandById);

// models
router.get('/models', ModelController.findAll);
router.get('/models/:id', ModelController.findById);
router.get('/models/:id/brands', ModelController.findBrandByModelId);
router.post('/models', ModelController.create);
router.patch('/models/:id', ModelController.updateModelById);
router.delete('/models/:id', ModelController.deleteModelById);

// vehicles
router.get('/:plate', VehicleController.findByPlate);

export default router;
EN

回答 1

Stack Overflow用户

发布于 2021-07-08 02:25:31

我偶然与一位同事解决了这个问题,他的IDE自动完成了导入文件的不同顺序,更确切地说,requiredAuthorization是路由器和测试中的最后一个导入,测试在那里顺利通过。

代码语言:javascript
复制
import * as express from 'express';
import * as healthcheck from 'express-healthcheck';
import requiredHeadersValidator from '../middlewares/required-headers-validator';
import cars from './cars';
import requiredAuthorization from '../middlewares/required-authorization';

就像这样,错误消除了(测试是用Jest做的),我想这可以帮助将来的人在发生一些奇怪的行为时考虑进口订单。

记者:如果有人知道这个命令为什么会影响这种行为,我会很乐意知道的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68290779

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档