【发布时间】:2026-01-16 03:55:01
【问题描述】:
我有一个带有 REST 之类的 API 的 MEAN 堆栈应用程序。我有两种用户类型:用户和管理员。为了让用户登录并保持会话,我像这样使用 jsonwebtoken jwt(简化):
const jwt = require("jsonwebtoken");
//example user, normally compare pass, find user in db and return user
let user = { username: user.username, userType: user.userType };
const token = jwt.sign({ data: user }, secret, {
expiresIn: 604800 // 1 week
});
为了保护我的特快路线,我这样做:
在这个例子中,它是一个“获取用户”路由,管理员可以获取任何给定用户的信息。 “普通”用户只被允许获取关于他/她自己的信息,为什么我将请求的用户名与从令牌解码的用户名进行比较。
let decodeToken = function (token) {
let decoded;
try {
decoded = jwt.verify(token, secret);
} catch (e) {
console.log(e);
}
return decoded;
}
// Get one user - admin full access, user self-access
router.get('/getUser/:username', (req, res, next) => {
let username = req.params.username;
if (req.headers.authorization) {
let token = req.headers.authorization.replace(/^Bearer\s/, '');
decoded = decodeToken(token);
if (decoded.data.userType == 'admin') {
//do something admin only
} else if (decoded.data.username == username) {
//do something user (self) only
} else{
res.json({ success: false, msg: 'not authorized' });
}
} else {
res.json({ success: false, msg: 'You are not logged in.' });
}
})
所以我的问题是,这有多安全?有人可以操纵会话令牌将用户名交换为其他人的用户名吗?甚至将用户类型从用户更改为管理员?
我的猜测是。只有当他们知道“秘密”,但这是否足够安全?秘密毕竟就像存储在代码中的纯文本密码一样。最佳做法是什么?
【问题讨论】:
-
你跑到
let user = { username: user.username, userType: user.userType };了吗? IIUC,这定义了一个变量user,它最初是undefined。然后是评估{...}的时候了,这涉及访问user.username。在undefined上查找username属性失败并出现 TypeError。 -
我不明白我是怎么遇到这个问题的,或者我不完全理解你的意思。正如我在代码中的注释所解释的,用户对象只是一个示例。通常会从数据库返回一个用户,如果不是,则会处理错误。
-
请忽略。您的示例代码令人困惑,但我想我理解您的意思。如果
jwt.verify失败并在decodeToken中出现异常,则if (decoded.data.userType == 'admin')中确实存在问题,因为decoded === undefined。也许考虑将decoded初始化为结构上有效的值,这意味着catch块中没有权限。此外,decoded可能应该在您的处理程序中使用let声明。 -
啊,是的。我想我明白你的意思。通常当 jwt.verify 失败时,它会生成一个响应,说“缓冲区错误,机密必须是字符串类型”......类似的东西。但是,然后它失败了,并且没有达到代码的“脆弱”部分,这是主要问题。不过,感谢您指出,我会尝试引发一些 jwt 错误并寻找解决方案。
标签: node.js rest security jwt mean-stack