首页 > 解决方案 > 嵌套函数调用在 express.js 中用 module.exports() 包装后不起作用

问题描述

将所有函数放入下面的类似内容后,嵌套函数调用不起作用module.exports()。在导出它们之前它曾经工作正常。

首先isValidCreds是被调用,它调用hasValidated,然后调用validateJWT

但是,当我运行服务器时,我只得到"isValidCreds is called". 问题是什么?

module.exports = {
  isValidCreds: function (req, res, next) {
      console.log("isValidCreds is called");
        if(hasValidated(req)){
            next();
        }
        res.status(401);
        res.end("Unauthorized");
  },
  hasValidated: function (req) {
    console.log("hasValidated is called");
    var authz = req.headers["authorize"];
    if(typeof authz !== 'undefined'){
      var authzParts = authz.split(" ");
      if(authzParts[0] === "Bearer"){

        if( validateJWT(authzParts[1]) ){
          console.log("Authorized");
          return true;
        }
      }
    }
    return false;
  },
  validateJWT: function (jwtstring) {
    console.log("validateJWT is called");
    var jwtParts = jwtstring.split(".");
    var header = JSON.parse(Buffer.from(jwtParts[0], 'base64').toString());
    var payload = JSON.parse(Buffer.from(jwtParts[1], 'base64').toString());
    var signature = jwtParts[2];

    var encodedHeader = Buffer.from(JSON.stringify(header)).toString('base64');
    var encodedPayload = Buffer.from(JSON.stringify(payload)).toString('base64');

    var username = payload.sub;
    currentUser = username;
    console.log("Verifying user:",username);

    var secret = secrets[username].secret;
    console.log("secret:",secret);
    var salt = payload.salt;
    secrets[username].salt = salt;

    var veriSign = CryptoJS.enc.Base64.stringify(
      CryptoJS.enc.Utf8.parse(
        CryptoJS.HmacSHA256(encodedHeader + "." + encodedPayload,salt + secret).toString(CryptoJS.enc.Hex)
      )
    );
    veriSign = veriSign.replace('/','_');
    veriSign = veriSign.replace('+','-');
    return veriSign === signature;
  }
};

标签: javascript

解决方案


因为hasValidated不再有具有名称的函数或变量,所以只有一个对象具有hasValidated分配匿名函数的属性。

您可以做的是创建常规功能并导出它们。这样,这些函数不依赖于对象:

function isValidCreds(req, res, next) {
  console.log("isValidCreds is called");
  if (hasValidated(req)) {
    next();
  }
  res.status(401);
  res.end("Unauthorized");
}

function hasValidated(req) {
  console.log("hasValidated is called");
  var authz = req.headers["authorize"];
  if (typeof authz !== 'undefined') {
    var authzParts = authz.split(" ");
    if (authzParts[0] === "Bearer") {

      if (validateJWT(authzParts[1])) {
        console.log("Authorized");
        return true;
      }
    }
  }
  return false;
}

function validateJWT(jwtstring) {
  console.log("validateJWT is called");
  var jwtParts = jwtstring.split(".");
  var header = JSON.parse(Buffer.from(jwtParts[0], 'base64').toString());
  var payload = JSON.parse(Buffer.from(jwtParts[1], 'base64').toString());
  var signature = jwtParts[2];

  var encodedHeader = Buffer.from(JSON.stringify(header)).toString('base64');
  var encodedPayload = Buffer.from(JSON.stringify(payload)).toString('base64');

  var username = payload.sub;
  currentUser = username;
  console.log("Verifying user:", username);

  var secret = secrets[username].secret;
  console.log("secret:", secret);
  var salt = payload.salt;
  secrets[username].salt = salt;

  var veriSign = CryptoJS.enc.Base64.stringify(
    CryptoJS.enc.Utf8.parse(
      CryptoJS.HmacSHA256(encodedHeader + "." + encodedPayload, salt + secret).toString(CryptoJS.enc.Hex)
    )
  );
  veriSign = veriSign.replace('/', '_');
  veriSign = veriSign.replace('+', '-');
  return veriSign === signature;
}

module.exports = {
  isValidCreds,
  validateJWT,
  hasValidated
};

exports或使用对象引用这些函数exports.hasValidated

module.exports = {
  isValidCreds: function (req, res, next) {
      console.log("isValidCreds is called");
        if(exports.hasValidated(req)){ // <===============
            next();
        }
        res.status(401);
        res.end("Unauthorized");
  },
  hasValidated: function (req) {
    console.log("hasValidated is called");
    var authz = req.headers["authorize"];
    if(typeof authz !== 'undefined'){
      var authzParts = authz.split(" ");
      if(authzParts[0] === "Bearer"){

        if( exports.validateJWT(authzParts[1]) ){ // <===============
          console.log("Authorized");
          return true;
        }
      }
    }
    return false;
  },
  validateJWT: function (jwtstring) {
    console.log("validateJWT is called");
    var jwtParts = jwtstring.split(".");
    var header = JSON.parse(Buffer.from(jwtParts[0], 'base64').toString());
    var payload = JSON.parse(Buffer.from(jwtParts[1], 'base64').toString());
    var signature = jwtParts[2];

    var encodedHeader = Buffer.from(JSON.stringify(header)).toString('base64');
    var encodedPayload = Buffer.from(JSON.stringify(payload)).toString('base64');

    var username = payload.sub;
    currentUser = username;
    console.log("Verifying user:",username);

    var secret = secrets[username].secret;
    console.log("secret:",secret);
    var salt = payload.salt;
    secrets[username].salt = salt;

    var veriSign = CryptoJS.enc.Base64.stringify(
      CryptoJS.enc.Utf8.parse(
        CryptoJS.HmacSHA256(encodedHeader + "." + encodedPayload,salt + secret).toString(CryptoJS.enc.Hex)
      )
    );
    veriSign = veriSign.replace('/','_');
    veriSign = veriSign.replace('+','-');
    return veriSign === signature;
  }
};

this.hasValidated也可以,但这是一个坏主意,因为对于读者来说,模块所依赖的函数导出的函数是否需要在该exports模块的 上调用并不明显。

所以像:

let {isValidCreds} = require('your module')

//....

app.use(isValidCreds)

如果你使用会失败this.hasValidated


推荐阅读