当我们在Node中使用jsonwebtoken时,我们为用户签名一个特定的令牌并将其发送回去。但是,当我们在用户在标头(Authentication: <token>)
中发送令牌时验证令牌时,jwt如何知道它正在验证的令牌是针对该特定用户的,而不是针对同样也在以下位置发送请求的其他用户同一时间?它是否将令牌存储在内部某个地方?
答案 0 :(得分:1)
在登录时,您签署了一个令牌,其中有效载荷是userId
,除了查询的用户对象中的_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如何知道它正在验证的令牌是给该特定用户的,而不是给同时发送请求的其他用户的?它是否将令牌存储在内部某个地方?
这是因为您提供的负载是用户唯一的。
答案 1 :(得分:0)
也许对您有用?
答案 2 :(得分:0)
从服务器发送令牌时,通常会使用用户ID对令牌进行签名。因此,当客户端随后发回该令牌时,您将其解码,它将把ID返回给您。然后用于在数据库中查找用户
答案 3 :(得分:0)
Authentication
令牌存储在身份验证服务器中,因此,当您在请求标头中发送Authentication
令牌时,身份验证服务器已验证您的客户。
在通过身份验证服务器进行身份验证之后,客户端现在可以传递JWT来对 Application Server 进行API调用。由于允许客户端进行API调用,因此应用程序服务器可以验证客户端已发送的JWT令牌并可以处理API调用。
请注意,要进行API调用,客户端必须为每个API调用发送一个Authorization: Bearer <token>
,该API存储在服务器(也称为授权服务器)中