[英]What is the proper implementation of a refresh token in JWT authentication
I'm trying to implement JWT authentication in my React & Nodejs application using jsonwebtoken .我正在尝试使用 jsonwebtoken 在我的 React 和 Nodejs 应用程序中实现JWT身份验证。
I currently have a JWT authentication in place that generates an access_token
when singing in. I want to properly implement JWT in my application so I'm looking to implement the use of a refresh_token
aswell.我目前有一个 JWT 身份验证,在唱歌时会生成一个
access_token
。我想在我的应用程序中正确实现 JWT 所以我希望实现对refresh_token
的使用。
My question: What is the best way of implementing this?我的问题:实现这一点的最佳方法是什么? How do I prevent a potential attacker with access to the user's
refresh_token
to gain access to protected resources?如何防止潜在的攻击者通过访问用户的
refresh_token
来访问受保护的资源?
Code:代码:
User sign in route with token creation:使用令牌创建的用户登录路由:
router.post("/login", async (req, res) => {
const { username, password, remember } = req.body;
if (!username || !password) {
return res.status(400).json({ message: "Please fill in all fields." });
}
try {
// find user based on username
const user = await User.findOne({ username });
if (isEmpty(user))
return res.status(400).json({ message: "User does not exists." });
// compare requested password to db password with bcrypt
const isValid = await bcrypt.compare(password, user.password);
if (!isValid)
return res.status(400).json({ message: "Invalid credentials" });
// sign a JWT token to user
const token = jwt.sign({ id: user.id }, config.get("jwtSecret"), { expiresIn: 3600, });
// if remember user === true sign a refresh token to the user
if(remember) {
const refreshToken = jwt.sign({ id: user.id }, config.get("jwtSecret"), { expiresIn: '30d'});
}
// send user & tokens to frontend
} catch (error) {
console.log(error);
}
My middleware that needs to succeed before accessing user data:我的中间件在访问用户数据之前需要成功:
function auth(req, res, next) {
const token = req.header("x-auth-token");
if (!token)
return res.status(401).json({ message: "No token, authorization denied." });
try {
const decoded = jwt.verify(token, config.get("jwtSecret"));
req.user = decoded;
next();
} catch (error) {
return res.status(400).json({ message: "Token is not valid" });
}
}
Using this middleware in my router for accessing user data:在我的路由器中使用这个中间件来访问用户数据:
// GET api/auth/user
// DESC get user data based on token
router.get("/user", auth, (req, res) => {
User.findById(req.user.id)
.select("-password")
.then((user) => {
return res.status(200).json({
user: {
id: user.id,
username: user.username,
email: user.email,
},
});
});
});
Where does my refresh_token
come in to place to finish off my secure JWT authentication?我的
refresh_token
在哪里完成我的安全 JWT 身份验证?
Your refresh token has 1 single job: Generate access tokens, thats'it, not give direct access to resources, this is access tokens job.您的刷新令牌有 1 个工作:生成访问令牌,仅此而已,不直接访问资源,这是访问令牌工作。
By doing that, you can put a short expire date on generated access tokens because you're gonna give user a chance to request an other once it expires.通过这样做,您可以在生成的访问令牌上设置一个较短的过期日期,因为一旦它过期,您将让用户有机会请求另一个。 I really don't see the point to store them in database.
我真的不明白将它们存储在数据库中的意义。
1- Concerning your bunch of code, use another key to sign your refresh tokens, don't use the same key for both. 1-关于你的一堆代码,使用另一个密钥来签署你的刷新令牌,不要对两者使用相同的密钥。
2- Make sure to store refresh tokens for every user in order to be able to revoke them if needed, and check that he owns them for real (database check). 2-确保为每个用户存储刷新令牌,以便能够在需要时撤销它们,并检查他是否真正拥有它们(数据库检查)。
3- Create a route (/token for example) that generates new access_tokens for users (here you need to check in database that user really owns refresh-token he's using). 3- 创建一个路由(例如/token),为用户生成新的access_tokens(在这里你需要检查用户真正拥有他正在使用的刷新令牌的数据库)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.