在我的 NodeJS 应用程序 RESTful API 中,当用户登录时,我创建一个 JWT 并将其以安全的 httponly cookie 发送到客户端:
const jwt = utils.createJWT(user._id.toString());
const sessionId = utils.generateSessionId();
res.cookie(sessionId, jwt, { httpOnly: true, secure: true });
return res.status(200).json({
userId: user._id,
result: constants.SUCCESS
});
登录后,后续API调用浏览器会自动将安全cookie发送到服务器。
我需要验证 JWT 是否已过期,如果已过期,则需要刷新 JWT。
但是在向服务器的请求中cookie似乎是加密的,那么如何提取JWT来检查它是否已过期?
最终我想做的是确保我可以验证 JWT 以查看它是否已过期,但我读到您不应该存储 JWT 服务器端,这是真的吗?我应该尝试提取 JWT来自安全 cookie,如果是的话怎么办?
如果您没有通过过期选项为您的 jwt 设置过期日期,那么您的 jwt 将永远不会过期。我建议将您的过期时间存储在 .env 中以提高安全性。如果你想在这里设置一个,你可以这样做:
(这里我使用 user._id 作为有效负载数据进行编码)
const signToken = id => {
return jwt.sign({ id }, process.env.JWT_SECRET_STRING, {
expiresIn: process.env.JWT_expires_in
});
};
const createSendToken = (user, statusCode, res) => {
const token = signToken(user._id);
const cookieOptions = {
expires: new Date(
Date.now() + process.env.JWT_COOKIE_EXPIRES_IN
),
httpOnly: true
};
if (process.env.NODE_ENV === 'production') {
// cookie will only sent on an encrypted connection
cookieOptions.secure = true;
}
res.cookie('jwt', token, cookieOptions);
接下来,检查您的令牌是否已过期: 您可以轻松验证您的令牌,并通过 jwt 的验证功能检查它是否已过期。我将使用基于承诺的方法:
const { promisify } = require('util');
// 1) verify token
const decoded = await promisify(jwt.verify)(
req.cookies.jwt,
process.env.JWT_SECRET_STRING
);
如果你console.log(解码)你会发现过期时间。您可以根据需要处理该错误。它们将是“JsonWebTokenError”和“TokenExpiredError”。 另请注意,jwt.verify 有异步和同步版本。 (在这里阅读更多内容:jwt.verify() 的 Node.js 回调)
但是,请记住 JWT 是一种无状态解决方案,非常适合 RESTful API。无需在服务器上存储会话状态。此外,如果用户的 jwt 已过期,请让他们再次登录,以便向他们颁发新的 jwt。您可以查看他们的文档以获取更多信息:https://www.npmjs.com/package/jsonwebtoken