如何使用令牌识别用户?

How to identify a user with a token?

我有一个名为“test”的 mongoDB Atlas 数据库,我只处理后端。

有 2 个集合:酱料和用户。 (是的,是关于酱汁的)

my database "test" with 2 collections

我需要确保只有在数据库中创建酱汁的用户才能删除这个酱汁。

从前端,在删除请求中,我确实收到了 2 个东西:一个令牌(用 jwt 制作)和要删除的酱汁的 ID。

The request of deletion

有了sauce的id我可以找到创建sauce的用户,也就是说我也可以在users集合中找到这个用户。对象用户有 2 个属性:电子邮件和密码(使用 bcrypt 散列)。

in the sauce object, we can find the id of the user who did create the sauce: userId

here is a user object in the users collection

所以我从前端 (req.body.token) 和产品 ID (req.params.id) 获得了令牌。

有了这个:我确实找到了创建对象的用户的 ID。

所以,我需要在令牌和用户 ID 之间创建一个 link。

我已尝试使用 jwt.sign 检查 userId 的值,并将其与收到的令牌进行比较。问题:此令牌在每次连接时都会发生变化,因此这不是正确的做法...

所以我的问题是:从后端(我无法触及前端)当我只有要删除的对象的 ID 和令牌时,我应该如何识别用户?

我建议您使用 Auth 中间件功能。在此函数中,您从 mongoDB 检索用户数据(按令牌搜索)并将用户传递给您的请求对象。

这样做,您将始终在所有经过身份验证的路由中拥有当前用户对象。

首先像这样更改您的 Auth 中间件:

const auth = async (req, res, next) => {
    try {
        // Try to find user
        const token = req.header('Authorization').replace('Bearer ', '')
        const decoded = jwt.verify(token, 'thejwtsecret')
        const user = await User.findOne({ _id: decoded._id, 'tokens.token': token }) 

        // If user not found, throw error
        if (!user) {
            throw new Error()
        }

        // Else, add user data and toke into request object
        req.token = token
        req.user = user
        
        // Keep going
        next()
    } catch (e) {
        // User not authenticated
        res.status(401).send({ error: 'Please authenticate.' })
    }
}
module.exports = auth

你说你有一个 Sauces 集合和一个删除路由,有了这个新的中间件,用户数据就可以在请求对象中轻松访问:

router.delete('/sauces', auth, async (req, res) => {
    // req.user is your current user object 
    // req.token is the token of the current user
});

带有 mongo db

的授权中间件
exports.verifyToken = async (req, res, next) => {


let token = req.body.token


if (token) {
jwt.verify(token, secret, async (err, decoded) => {
  if (err) {
    return res.status(400).send({
      success: false,
      message: 'Failed to authenticate token.'
    }).status(401)
  } else {
    const User = await dbSchema.User.findOne({ _id: decoded._id }).exec();
    if (User ) {
      req.body.decoded = decoded._id
      return next()
    }
    else {
      return res.status(400).send({
        success: false,
        message: 'Token Expired.'
      }).status(401)
    }
  }
})


 }



else {
return res.status(400).send({
  success: false,
  message: 'Token Required.'
}).status(401)


}
}