如何为 passport.authenticate 创建可重复使用的代码?

How to create a reusable code for passport.authenticate?

我有多个控制器,每个控制器都有多个方法。在每种方法中,我都对用户进行身份验证,并使用身份验证返回的用户 ID 从数据库中获取数据。我正在尝试创建可重用的身份验证代码,因为代码是重复的。

在控制器中:

const authenticate = require('../utils/user-authenticate');

exports.getData = async (req, res, next) => {
    const userId = await authenticate.user(req, res, next);
    console.log(userId);
};

并且在身份验证中我有:

exports.user = (req, res, next) => passport.authenticate('jwt', async (error, result) => {
    if (error) {
      // Send response using res.status(401);
    } else {
      return result;
    }
})(req, res, next);

console.log(userId); 总是打印 undefined。这是在护照完成之前打印的。看起来 async/await 没有按照我想要的方式工作。

如果我使用 await authenticate.user(req, res, next).then() 它可以工作,但是不能将结果直接分配给 userId 变量吗?

如果我使用 return next('1'):第一次 undefined 但第二次它打印 1.

感谢@Estradiaz 的建议:

exports.user returns undefined ... Return is scoped within inner callback - if you want to pass it outside wrap it into a promise

可重复使用passport.authenticate:

exports.user = (req, res) => {
    return new Promise(resolve => {
        passport.authenticate('jwt', null, async (error, result) => {
            if (error) {
                email.sendError(res, error, null);
            } else if (result) {
                resolve(result);
            } else {
                return res.status(401).json({errors: responses['1']});
            }
        })(req, res);
    });
};

这就是我在我的控制器中使用它的方式,例如在一个函数中:

exports.getData = async (req, res, next) => {
   const userId = await authenticate.user(req, res);
};

包装成承诺:

exports.user = (req, res, next) => new Promise((resolve, reject) => {
  passport.authenticate('jwt', async (error, result) => {
    if (error) {
      // reject(error)
      // Send response using res.status(401);
    } else {

      resolve(result);
    }
  })(req, res, next);
})

但想想:

//app.use or something similar
addMiddleware(authJWT);
// later in the chain
useMiddleware((req, res, next)=>{
   // test auth or end chain
   if(!req.JWT_user) return; 
   req.customField = 'one for the chain'
   // process next middleware
   next()
});