在登录时,您签署了一个令牌,其中 payload 是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 如何知道它正在验证的令牌是针对该特定用户的,而不是针对同时发送请求的其他用户的?它是否将令牌存储在内部某处?
这是因为您提供的有效负载是用户独有的。