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

时间:2019-09-23 19:41:13

标签: javascript node.js passport.js

我有多个控制器,每个控制器都有多种方法。在每种方法中,我都对用户进行身份验证,并使用从身份验证返回的用户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。

2 个答案:

答案 0 :(得分:2)

兑现了诺言:

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()
});

答案 1 :(得分:0)

感谢@Estradiaz的建议:

  

exports.user返回未定义...返回范围在内部   回调-如果您想将其传递到外部,则将其包装为一个诺言

可重复使用的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);
};