【问题标题】:How to identify a user with a token?如何使用令牌识别用户?
【发布时间】:2021-03-08 18:22:09
【问题描述】:

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

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

my database "test" with 2 collections

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

从前端,在删除请求中,我确实收到了两件事:一个令牌(用 jwt 制作),以及要删除的酱汁的 id。

The request of deletion

通过酱汁的 id,我可以找到创建酱汁的用户,这意味着我也可以在用户集合中找到用户。对象用户有 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。

所以,我需要在令牌和 userId 之间建立一个链接。

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

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

【问题讨论】:

    标签: mongodb api jwt token backend


    【解决方案1】:

    使用 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)
    
    
    }
    }
    

    【讨论】:

    • 非常感谢,我要试试这个,我会告诉你它是否也能解决我的问题。
    【解决方案2】:

    我建议您使用 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
    

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

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

    【讨论】:

      猜你喜欢
      • 2018-12-27
      • 1970-01-01
      • 2016-04-06
      • 2019-01-24
      • 2018-07-24
      • 2013-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多