所以我已经阅读了一些在您的网站上实施刷新令牌的方法,但我无法理解它,因为布局与我学校的项目布局非常不同。有谁知道我如何实现我的代码风格?它基本上遵循 MVC 指南,包括模型、路由、控制器。
jwtMiddleware.js:
//////////////////////////////////////////////////////
// REQUIRE DOTENV MODULE
//////////////////////////////////////////////////////
require("dotenv").config();
//////////////////////////////////////////////////////
// REQUIRE JWT MODULE
//////////////////////////////////////////////////////
const jwt = require("jsonwebtoken");
//////////////////////////////////////////////////////
// SET JWT CONFIGURATION
//////////////////////////////////////////////////////
const secretKey = process.env.JWT_SECRET_KEY;
const tokenDuration = process.env.JWT_EXPIRES_IN;
const tokenAlgorithm = process.env.JWT_ALGORITHM;
//////////////////////////////////////////////////////
// MIDDLEWARE FUNCTION FOR GENERATING JWT TOKEN
//////////////////////////////////////////////////////
module.exports.generateToken = (req, res, next) => {
const payload = {
userId: res.locals.userId,
timestamp: new Date()
};
const options = {
algorithm: tokenAlgorithm,
expiresIn: tokenDuration,
};
const callback = (err, token) => {
if (err) {
console.error("Error jwt:", err);
res.status(500).json(err);
} else {
res.locals.token = token;
next();
}
};
const token = jwt.sign(payload, secretKey, options, callback);
};
//////////////////////////////////////////////////////
// MIDDLEWARE FUNCTION FOR SENDING JWT TOKEN
//////////////////////////////////////////////////////
module.exports.sendToken = (req, res, next) => {
res.status(200).json({
message: res.locals.message,
token: res.locals.token,
});
};
//////////////////////////////////////////////////////
// MIDDLEWARE FUNCTION FOR VERIFYING JWT TOKEN
//////////////////////////////////////////////////////
module.exports.verifyToken = (req, res, next) => {
const authHeader = req.headers.authorization;
console.log("hi")
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return res.status(401).json({ error: 'No token provided' });
}
const token = authHeader.substring(7);
if (!token) {
return res.status(401).json({ error: "No token provided" });
}
const callback = (err, decoded) => {
if (err) {
return res.status(401).json({ error: "Invalid token" });
}
console.log(decoded.userId)
res.locals.userId = decoded.userId;
res.locals.tokenTimestamp = decoded.timestamp;
next();
};
jwt.verify(token, secretKey, callback);
};
.env:
JWT_EXPIRES_IN=50m
JWT_ALGORITHM=HS256
REFRESH_TOKEN_EXPIRES_IN=7d
mainRoutes.js:
router.post("/login", userController.login, bcryptMiddleware.comparePassword, jwtMiddleware.generateToken, jwtMiddleware.sendToken);
router.post("/register", userController.checkUsernameOrEmailExist, bcryptMiddleware.hashPassword, userController.register, userController.login, jwtMiddleware.generateToken, jwtMiddleware.sendToken);
我尝试将令牌刷新设置为 7 天后过期。然后使访问令牌持续 1 分钟。添加了另一个控制器,无论访问令牌持续多久,因此当它过期时,它将改用刷新令牌。但这可能是错误的方法,因为我不明白如何真正实现它
这是一个要点希望它有帮助
访问令牌的生命周期较短,例如 15 分钟。刷新令牌的寿命很长,例如 30 天。
当用户登录时,他们应该收到访问令牌和刷新令牌,安全地存储这些令牌(不是以纯文本形式存储在本地存储中,使用安全的 cookie 和加密),并尽可能避免在客户端代码中公开它们。
发出 api 请求时,应在标头中发送访问令牌
端点应验证令牌,如果过期,则应响应访问令牌已过期
然后客户端应该查看“令牌已过期”响应,并尝试通过使用刷新令牌向端点请求一个更新的访问令牌来获取更新的访问令牌
API 随后应使用新的访问令牌或刷新令牌过期错误进行响应
如果刷新令牌已过期,应提示用户重新登录