无法转到下一个中​​间件 - NodeJS

Can't go to the next middleware - NodeJS

我正在使用 express 并且 router 来创建一个带有 public 和私有路由的服务器。要访问专用路由,用户必须登录并发送 JWT 令牌。令牌很好,但我无法将用户重定向到私有路由。

const express = require('express');
const jwt = require('jsonwebtoken');

const authRouter = require('./auth');
const usersRouter = require('./users');

const router = express.Router();

router.use(authRouter);

const accessTokenSecret = '4-8-15-16-23-42';
const privateRoutes = ['/user'];

const checkPublicOrPrivate = (req, res, next) => {
  privateRoutes.forEach(route => {
    if (req.path.includes(route)) {
      return authorization(req, res, next);
    }
  });

  return next();
};

const authorization = (req, res, next) => {
  const { token } = req.headers;
  if (token) {
    jwt.verify(token, accessTokenSecret, (err, user) => {
      if (err) {
        return res.status(403).send('Forbiden, access denied');
      }
      console.log(user); //{ username: 'username', iat: 1603288443 }
      return next(); //Should go to the next middleware
    });
  }

  return res.status(403).send('Bad message') //But always hits this message or the 404 one
};

router.use(checkPublicOrPrivate);
router.use(authorization); //Also tried without this line
router.use(usersRouter);

router.use(function(req, res, next) {
  res.status(404).send('404 not found!');
});

router.use(function(err, req, res, next) {
  res.status(500).send('Server error');
});

module.exports = router;

那是因为jwt.verify是异步的(有回调函数)。 在验证您的令牌时,代码会继续执行。下一行要执行的是res.status(403).send('Bad message'),所以它总是被执行。

解决方案是用 else 语句

换行
const authorization = (req, res, next) => {
  const { token } = req.headers;
  if (token) {
    jwt.verify(token, accessTokenSecret, (err, user) => {
      if (err) {
        return res.status(403).send('Forbiden, access denied');
      }
      console.log(user);
      return next();
    });
  } else { // add 'else'
      res.status(403).send('Bad message'); // This line will only be executed if there's no token
  }
};

你应该尝试类似的东西

// the middleware
authenticateToken =  function (req, res, next) {
    const cookie = new Cookie(req ,res , {})
    const token = cookie.get('access_token',{signed:false})
  
    if (token == null)  res.redirect('login',401); //TODO: redirect to login with a small message
  
    jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, user) => {
      if (err) {
         authMethods.refreshToken(req,res,next);
      }else{
        req.user = user
        next()
      }
      
    })
  }

然后在你的路线上

// the route ...
router.get('/', authenticateToken, function (req, res, next) {
  if (!req.user.email) {
    res.render('login', { message: "please login again" });
  }
  const userEmail = authMethods.data.dailyReportNameTable(req.user.email)
 console.log(userEmail)
  res.render(userEmail)

});