【问题标题】:Why is my response call out of scope and not working? NodeJs, Bcrypt, Express, MySQL为什么我的响应调用超出范围并且不起作用? NodeJs、Bcrypt、Express、MySQL
【发布时间】:2021-10-07 07:35:26
【问题描述】:

我正在使用 Nodejs 和 MySQL 来验证用户密码。我很难访问我的响应 (res) 对象以将响应发送回客户端。出于某种原因,它在我的 bcrypt 函数之上工作,但不在下面。我需要在下面访问它,以便我可以将我的 JWT 令牌发送回客户端。请参阅下面的代码示例。谢谢。

**WORKING EXAMPLE**
**res.send(data) is properly sending data back to the client**

app.post("/login", jsonParser,(req, res) => {
    let selectQuery = 'SELECT * FROM ?? WHERE ?? = ?';  
    let query = mysql.format(selectQuery,["users","username", req.body.username]);

    pool.query(query,(err, data) => {
        if(err) {
            console.error(err);
        }
//works here---> res.send(data)

        let match = bcrypt.compareSync(req.body.password, 
        data[0].password)
        console.log(match)
        
        match ? token = generateToken(data[0]): token = null
    })
})
**NON-WORKING EXAMPLE** 
**res.send(data) is NOT sending data back to the client. TIMED OUT**

   app.post("/login", jsonParser,(req, res) => {
    let selectQuery = 'SELECT * FROM ?? WHERE ?? = ?';  
    let query = mysql.format(selectQuery,["users","username", req.body.username]);

    pool.query(query,(err, data) => {
        if(err) {
            console.error(err);
        }
     
        let match = bcrypt.compareSync(req.body.password, data[0].password)
        console.log(match)

//not here----> res.send(data)
    
        match ? token = generateToken(data[0]): token = null
    })
})

**The same code using try catch**
app.post("/login", jsonParser,(req, res) => {
    let selectQuery = 'SELECT * FROM ?? WHERE ?? = ?';  
    let query = mysql.format(selectQuery,["users","username", req.body.username]);

    pool.query(query,(err, data) => {
        if(err) {
            console.error(err);
        }
        try {
            let match = bcrypt.compareSync(req.body.password, data[0].password)
            match ? token = generateToken(data[0]): token = null
          }
          catch (exception_var) {
           console.log('exception', exception_var)
          }
          finally {
            res.send(token)
          }
    })
})

function generateToken(data) {
    const secret = process.env.JWT_SECRET;
    console.log('inside generate token!', data)
    const payload = {
      data: data.username,
      //department: data.department,
      subject: data.id,
    };
    console.log(payload,'payload')
    const options = {
      expiresIn: "1d",
    };
    return jwt.sign(payload, secret, options);
    
  }

【问题讨论】:

  • 嗨!欢迎来到stackoverflow!几个问题:compare() 返回什么?你可以在最后 3 行周围添加一个 try-catch 块吗?我认为它抛出了一个错误,并且响应永远不会发回
  • @germanio 嗨,谢谢!我已经更新了上面的代码,使其更具可读性。我的比较同步函数使用正确的密码返回 true,使用不正确的密码返回 false。我添加了 try catch 但它没有抛出任何错误,它仍然不会发送响应。它可以很好地验证我的密码并生成令牌,但不会发送任何类型的响应。谢谢。

标签: mysql node.js api express scope


【解决方案1】:

bcrypt.compare 是一个异步函数。因此,您可以通过两种方式使用它。使用回调函数或使用异步等待

app.post("/login", jsonParser,(req, res) => {
    let selectQuery = 'SELECT * FROM ?? WHERE ?? = ?';  
    let query = mysql.format(selectQuery,["users","username", req.body.username]);
    pool.query(query, async (err, data) => {   // Declare the function as async function
        if(err) {
            return console.error(err);
        }
        const match = await compare(req.body.password, data[0].password)   // wait for the data from function
        const token = match ? generateToken(data[0]) : null
        res.send(token)
    })
})

【讨论】:

  • 您好普拉纳,感谢您的回复。当我将 await 添加到如上所示的代码中时,我得到 err: SyntaxError: await is only valid in async functions and the top level body of modules.
  • 是否添加了 pool.query(query, async (err, data) => { 这一行。(考虑添加 async 关键字)
  • 嗨 Prana,我将 async 添加到 pool.query 参数中,它消除了我的 async await 错误,但我仍然无法在 bcrypt 函数之后发送服务器响应。我可以看到该函数正在返回 true 并生成我的令牌,但我无法发送响应。我的console.log(match)函数工作后但不是res.send()。谢谢。
  • 在您的回复中,您只需发送查询的结果。还是您需要从比较功能发送响应?
  • 我需要得到结果 ---> 使用 bcrypt 进行比较 ---> 生成令牌 ---> 在响应中将令牌发送给用户。
猜你喜欢
  • 2013-12-07
  • 2018-08-27
  • 2015-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-06
相关资源
最近更新 更多