【问题标题】:Using async/await correctly in the context of token validation在令牌验证的上下文中正确使用 async/await
【发布时间】:2020-04-03 21:07:13
【问题描述】:

我正在为使用 Google 登录验证用户的网站构建 Express.js 后端。

而且,我正在尝试创建一个 RESTful API 调用:

  1. 接受一个 IDtoken。
  2. 使用 Google 的 OAuth2 库验证该令牌。
  3. 检查用户是否在 MongoDB 集合中,然后:
  4. 如果为真则返回访问令牌,如果为假则不返回任何内容。

这就是我目前所拥有的......

发帖请求:

//recieve token id from frontend, verify it, and send session back in response
router.post('/google', (req, res) => {
  const idToken = req.body.tokenID;
  const accessToken = req.body.accessToken;
  const client = new OAuth2Client(keys.google.clientID);

  const session = verify(idToken, accessToken, client).catch(console.error);
  console.log('Session: ', session)
  return res.send(session);
});

验证():

//verify token
async function verify(idToken, accessToken, client) {

  const ticket = await client.verifyIdToken({
    idToken: idToken,
    audience: keys.google.clientID,
  });

  const payload = ticket.getPayload();
  const email = payload['email'];

  if (findUser(email)) {
     return {
      email: email,
      accessToken: accessToken
    };
  } else {
    return null;
  }
}

查找用户():

//find user
function findUser(email) {

  User.find({email: email}, (error, user) => {
    if(error) {
      console.log(error);
      return false;
    } else if (user.length === 0) {
      console.log('this user is not in the database');
      return false;
    } else {
      console.log('this user is in the database');
      return true;
    }
  });
}

对于输出,无论用户是否在数据库中,我总是得到:

Session:  Promise { <pending> }
this user is in the database

Session:  Promise { <pending> }
this user is not in the database

我知道,因为 verify() 是一个异步函数,我需要在将它分配给变量之前让它解决它的承诺,但我不知道如何正确地做到这一点,不幸的是,我不能t 使 verify() 成为同步函数,因为它在从 Google 库调用 getPayload() 之前没有正确创建票证对象。

关于如何以正确的顺序完成这一切的任何想法?

谢谢。

【问题讨论】:

    标签: javascript node.js express async-await google-signin


    【解决方案1】:

    你能不能试试:

    //recieve token id from frontend, verify it, and send session back in response
    router.post('/google', async (req, res) => {
      const idToken = req.body.tokenID;
      const accessToken = req.body.accessToken;
      const client = new OAuth2Client(keys.google.clientID);
    
      const session = await verify(idToken, accessToken, client).catch(console.error);
      console.log('Session: ', session)
      return res.send(session);
    });
    

    更新 - 查找用户:

    //find user
    async function findUser(email) {
    
      const user = await User.find({email: email}, (error, user) => {
        if(error) {
          console.log(error);
          return false;
        } else if (user.length === 0) {
          console.log('this user is not in the database');
          return false;
        } else {
          console.log('this user is in the database');
          return true;
        }
      });
     return user;
    }
    

    【讨论】:

    • 当我这样做时,变量“session”现在每次都设置为 null。所以,它解决了,但似乎它现在从不等待 findUser() ?
    • 好的 - 让我看看 findUseR()
    • 我添加了 findUser() 示例 - 请注意,由于我是动态编写的,因此可能存在轻微的语法错误。让我知道你的进展情况:)
    • 进步! session 变量现在填充了正确的对象,但现在它永远不会像在 db 中找不到用户时那样变为 null。我尝试将 findUser 设置为根据 user.length 是否大于 0 返回 true 或 false,因为我不确定返回用户数组是空的还是满的仍然会使 if(findUser(email)) 为真,但这好像没什么效果……
    • 我想我找到了解决方法。我没有在 verify() 中调用 findUser() ,而是将其移到 post 请求中的 verify() 之后发生。这仍然需要使两个函数异步并等待它们的逻辑,但它更容易遵循,并且似乎每次都能按预期工作。不过感谢您的时间!我不认为我会自己想出来。
    猜你喜欢
    • 2013-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-23
    • 1970-01-01
    • 2018-01-28
    • 1970-01-01
    相关资源
    最近更新 更多