我正在使用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中的请求没有完成...任何帮助将不胜感激:)
1条答案
按热度按时间zbsbpyhn1#
问题就在这里。。
直接从中间件返回而不调用
next()
或res.send()
会导致Express永远不会发送响应。您需要匹配前面的错误处理模式并使用以下代码
至于为什么这可能会使
iat
属性无效,请记住JavaScript时间戳是以毫秒为单位的。1685432169
是1970-01-20T12:10:32.169Z
,但1685432169 * 1000
是2023-05-30T07:36:09.000Z