jwt刷新后req.user丢失数据
Posted
技术标签:
【中文标题】jwt刷新后req.user丢失数据【英文标题】:req.user losing data after jwt refresh 【发布时间】:2021-04-13 15:31:52 【问题描述】:首先让我提供所有相关代码,然后我将解释我的问题
我的中间件来验证 jwt
module.exports.authenticateToken = (req, res, next) =>
const authHeader = req.headers["authorization"];
const token = authHeader && authHeader.split(" ")[1];
if (!token)
return res.status(401).json( success: false, msg: "not authorized" );
jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, user) =>
if (err)
return res
.status(403)
.json( success: false, msg: "jwt cannot be verified" );
req.user = user;
next();
);
;
生成访问和刷新令牌的代码
module.exports.generateAccessToken = (user) =>
const payload =
sub: user._id,
name: user.username,
;
return jwt.sign(payload, process.env.ACCESS_TOKEN_SECRET,
expiresIn: "20s",
);
;
module.exports.generateRefreshToken = (user) =>
const payload =
sub: user._id,
name: user.username,
;
return jwt.sign(payload, process.env.REFRESH_TOKEN_SECRET);
这就是用户登录时发生的情况(我将刷新令牌存储在数组 rn 中,当我让所有这些正常工作时,我会更改它)
module.exports.postAuthLogin = async (req, res) =>
const username, password = req.body;
try
const user = await User.findOne( username );
if (!user)
return res.status(401).json( success: false, msg: "Invalid username" );
const passwordIsValid = validatePasswordHash(
password,
user.salt,
user.hash
);
if (!passwordIsValid)
return res.status(401).json( success: false, msg: "Invalid password" );
const accessToken = generateAccessToken(user);
const refreshToken = generateRefreshToken(user);
refreshTokens.push(refreshToken);
res.status(200).json( success: true, accessToken, refreshToken );
catch (err)
return res.json( msg: err.toString() );
;
最后,这是当用户请求刷新令牌时运行的内容
module.exports.postAuthRefreshToken = (req, res) =>
const refreshToken = req.body;
if (!refreshToken)
return res
.status(401)
.json( success: false, msg: "must provide a refresh token" );
if (!refreshTokens.includes(refreshToken))
return res.status(403).json(
success: false,
msg: "refresh token was deleted you must login again",
);
jwt.verify(refreshToken, process.env.REFRESH_TOKEN_SECRET, (err, user) =>
const accessToken = generateAccessToken(user);
res.status(200).json( success: true, accessToken );
);
;
所以我的问题最初是当我登录并获取刷新和访问令牌时,然后我请求一个受 authenticateToken 中间件保护的路由,我在该路由中的 req.user 看起来像这样
sub: '5ff5f16f4203ade4d1b63da8',
name: 'test1',
iat: 1610055109,
exp: 1610055129
但是当我的令牌过期并且我请求一个新令牌时,它确实得到验证并且我能够访问受保护的路由但是我的 req.user 看起来像这样
iat: 1610055143, exp: 1610055163
我已经为这个问题苦苦挣扎了一段时间,所以任何帮助都将不胜感激,如果您需要更多信息,只需说点什么,生病 100% 提供它
【问题讨论】:
【参考方案1】:问题来了
jwt.verify(refreshToken, process.env.REFRESH_TOKEN_SECRET, (err, user) =>
const accessToken = generateAccessToken(user);
res.status(200).json( success: true, accessToken );
);
“用户”实际上是解码后的有效载荷
sub: '5ff5f16f4203ade4d1b63da8',
name: 'test1',
iat: 1610055109,
exp: 1610055129
然后您将其传递给 generateAccessToken 并尝试访问未定义的字段 _id 和用户名。
您可以将有效负载字段更改为
_id: '5ff5f16f4203ade4d1b63da8',
username: 'test1',
iat: 1610055109,
exp: 1610055129
因此,当传递解码后的有效负载时,它仍然具有相同的字段名称。 或者您可以使用 payload.sub 再次从 DB 中获取用户,然后将用户传递给 generateAccessToken。
【讨论】:
OHHHHH,我明白了,谢谢你,当我看到用户时,我立刻想到,由于某种原因,它会拥有我的用户应该拥有的所有正常字段。我会重构它,但谢谢以上是关于jwt刷新后req.user丢失数据的主要内容,如果未能解决你的问题,请参考以下文章