【问题标题】:Token Authentication - JWT令牌认证 - JWT
【发布时间】:2020-09-25 10:03:22
【问题描述】:

当我们在 Node 中使用 jsonwebtoken 时,我们会为用户签署一个特定的令牌并将其发回。但是,当我们在用户在标头(Authentication: <token>) 中发送令牌时验证令牌时,jwt 如何知道它正在验证的令牌是针对该特定用户而不是针对同时发送请求的其他用户时间?它是否将令牌存储在内部某处?

【问题讨论】:

    标签: javascript node.js express jwt jwt-auth


    【解决方案1】:
    1. 令牌最多存储在客户端中
    2. token验证成功后,我们会得到一些用户信息,比如account id,所以我们可以使用account id在数据库中查找更多的用户信息,并检查使用是否真实存在

    也许对你有用?

    【讨论】:

      【解决方案2】:

      从服务器发送令牌时,您通常会使用用户 ID 对令牌进行签名。因此,当客户端然后发送回该令牌时,您对其进行解码,它将返回 id 给您。然后您可以使用它在数据库中查找用户

      【讨论】:

        【解决方案3】:

        在登录时,您签署了一个令牌,其中 payloaduserId,只不过是查询的用户对象中的_id 字段。

        loginUser: async (req, res, next) => {
            try {
              const { email, password } = req.body
              const user = await User.findOne({ email })
              const token = auth.signToken({ userId: user._id })
              res.status(200).json({ user, token })
            } catch (error) {
              return next(error)
            }
          }
        

        auth.js

        function signToken(payload) {
          return jwt.sign(payload, JWTSECRET)
        }
        
        function verifyToken(req, res, next) {
          const token = req.headers.Authorization || req.headers.authorization || ""
          if (!token) {
            return res.status(403).json({ error: "Not authorized" })
          }
        
          jwt.verify(token,JWTSECRET, (err, decodedObj) => {
            if (err) {
              return res.status(403).json({ error: "Not authorized" })
            }
        
            req.user = decodedObj
            next()
          })
        }
        
        module.exports = { signToken, verifyToken }
        


        jwt.verify的回调中,你会得到一个decodedObj,就像:

        { userId: '5edb3ae6d6b129183c1393bc', iat: 1591425786 }
        

        其中 iat 是发出 jwt 的时间。


         req.user = decodedObj
        

        这里,我们将解码后的数据“附加”到用户对象上,这样当对受保护路由发出请求时,我们可以从请求对象中获取userId,如req.user.userId,然后查询它来自数据库。


        当您签署令牌时,您提供了一个有效负载,它可以是userId 和一个秘密。因此,令牌被签名。之后,您需要验证令牌,以防您尝试访问需要令牌的受保护页面。

        因此,当您向该受保护路由发送请求时,如下所示:

           router.get("/me", auth.verifyToken, usersController.identifyUser)
        

        其中identifyUser 是一个控制器函数,它仅通过检查userId 来识别登录用户(记住用户对象包含解码的对象数据)。


        jwt 如何知道它正在验证的令牌是针对该特定用户的,而不是针对同时发送请求的其他用户的?它是否将令牌存储在内部某处?

        这是因为您提供的有效负载是用户独有的。

        【讨论】:

        • 所以需要在verifyToken后手动检查用户是否在数据库中?您能否详细说明该控制器功能?
        • 对不起,你是什么意思?我不关注。
        【解决方案4】:

        Authentication 令牌存储在 Authentication Server 中,因此当您在请求标头中发送 Authentication 令牌时,Authentication Server 对您的客户端进行了身份验证。

        通过Authentication Server认证后,客户端现在可以通过JWT对Application Server进行API调用。由于允许客户端进行 API 调用,Application Server 可以验证客户端发送的 JWT 令牌并可以处理 API 调用。

        请注意,为了进行 API 调用,客户端必须为每个 API 调用发送一个Authorization: Bearer <token>,它存储在服务器(也称为授权服务器)中

        【讨论】:

          猜你喜欢
          • 2020-10-24
          • 2022-12-04
          • 2019-05-01
          • 1970-01-01
          • 2019-08-09
          • 2020-10-07
          • 2020-04-22
          • 2019-04-20
          • 2017-05-27
          相关资源
          最近更新 更多