NodeJS Postman无法使用其环境变量完成对JWT的请求

qncylg1j  于 2023-06-05  发布在  Node.js
关注(0)|答案(1)|浏览(147)

我正在使用node,express为一个项目制作一个REST API,其中用户首先注册或登录并获得一个JWT令牌作为响应。使用注册或登录时收到的JWT令牌,用户可以访问我的应用程序的一些受保护路由。
当我尝试在postman中设置一个名为jwt的环境变量以使用该令牌进行授权时,然后请求到该特定的受保护路由(Get all图尔斯),该路由需要用户在访问它之前被授权或登录,它不会完成,它只是显示“发送请求”。
下面是我的受保护路由控制器:

exports.protect = catchAsync(async (req, res, next) => {
  // 1) Getting the token & checking if it's there
  let token;
  if (
    req.headers.authorization &&
    req.headers.authorization.startsWith('Bearer')
  ) {
    console.log(req.headers);
    token = req.headers.authorization.split(' ')[1];
    console.log(token);
  }

  if (!token) {
    return next(
      new AppError('You are not logged in. Please login to access', 401)
    );
  }
  // 2) Verification of the token
  // const decoded = await promisify(jwt.verify)(token, process.env.JWT_SECRET); //decoded is the payload of the jwt
  let decoded;
  try {
    decoded = jwt.verify(token, process.env.JWT_SECRET);
    console.log(decoded);
  } catch (err) {
    console.log(err);
    return next(err);
  }

  // 3) Check if user still exists
  const currentUser = await User.findById(decoded.id);
  console.log(currentUser);
  if (!currentUser) {
    return next(
      new AppError('The user belongining to this token does not exist.', 401)
    );
  }

  // 4) Check if user changed the password after the token was issued
  if (currentUser.changedPasswordAfter(decoded.iat)) {
    return new AppError(
      'User recently changed password. Please login again.',
      401
    );
  }

  //GRANT ACCESS TO THE PROTECTED ROUTE
  req.user = currentUser;
  next();
});

第一个console.log(req.headers.authorization)的结果是:'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY0NzM0YzY1Yzc0ZDUyNzJhMDQwYWQ2ZSIsImlhdCI6MTY4NTQyOTc1MCwiZXhwIjoxNjkzMjA1NzUwfQ.b-x0SH1GAFmQ7ZrDGzgqcd2HShDwclmb7d4oKk6lDlk',
第二个console.log(token)的结果是:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY0NzM0YzY1Yzc0ZDUyNzJhMDQwYWQ2ZSIsImlhdCI6MTY4NTQyOTc1MCwiZXhwIjoxNjkzMjA1NzUwfQ.b-x0SH1GAFmQ7ZrDGzgqcd2HShDwclmb7d4oKk6lDlk
第三个console.log(decoded)的结果是:{ id: '64734c65c74d5272a040ad6e', iat: 1685432169, exp: 1693208169 }
第四个console.log(currentUser)的结果是:{ _id: new ObjectId("64734c65c74d5272a040ad6e"), name: 'John', email: 'john@gmail.com', __v: 0 }
所有结果都符合预期和正确。
在代码中,当我使用“Authorization”而不是“authorization”时,postman中的请求完成,但代码无法读取req.headers.Authorization的值,因为“Authorization”总是未定义的,因为req.headers中的属性称为“authorization”。有了“授权”,我总是从我的错误控制器中得到“你没有登录”的错误,尽管我已经登录并有一个有效的JWT令牌。
以下是我的 Postman 截图:

我比较了我的代码与教师的代码,以及通过我的学习和代码是相同的。我认为有一些 Postman 的问题,虽然我的 Postman 是最新的。我花了几个小时进行调试,发现问题只出在代码中的“授权”上。当我使用“授权”而不是“授权”时, Postman 完成了请求,但总是给予我错误,因为用户没有登录访问受保护的路由。另一方面,当我使用“授权”时,因为实际代码来自讲师,Postman中的请求没有完成...任何帮助将不胜感激:)

zbsbpyhn

zbsbpyhn1#

问题就在这里。。

if (currentUser.changedPasswordAfter(decoded.iat)) {
   return new AppError(
     'User recently changed password. Please login again.',
     401
   );
 }

直接从中间件返回而不调用next()res.send()会导致Express永远不会发送响应。
您需要匹配前面的错误处理模式并使用以下代码

if (currentUser.changedPasswordAfter(decoded.iat)) {
  return next(
    new AppError("User recently changed password. Please login again.", 401)
  );
}

至于为什么这可能会使iat属性无效,请记住JavaScript时间戳是以毫秒为单位的。
16854321691970-01-20T12:10:32.169Z,但1685432169 * 10002023-05-30T07:36:09.000Z

相关问题