【问题标题】:req.user losing data after jwt refreshjwt刷新后req.user丢失数据
【发布时间】: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% 提供它

【问题讨论】:

    标签: node.js express jwt authorization


    【解决方案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,我明白了,谢谢你,当我看到用户时,我立刻想到,由于某种原因,它会拥有我的用户应该拥有的所有正常字段。我会重构它,但谢谢
    猜你喜欢
    • 2020-11-19
    • 2019-03-24
    • 2017-01-04
    • 1970-01-01
    • 2017-10-12
    • 1970-01-01
    • 2016-01-26
    • 2021-06-28
    • 2016-12-25
    相关资源
    最近更新 更多