我目前正在使用express作为我的react应用程序的后端。为了保护某些路线,我使用通行证JWT来确保用户登录并具有有效的令牌,以便访问应用程序的各个部分。
我可能有多条路线,有些所有用户都可以访问,有些只有特定用户可以访问。例如:
所有登录的人都可以访问 /api/online
。
/api/users/
仅应由具有特定权限的用户访问。
这些权限在用户的MongoDB文档中预先设置为数组。
用户登录后,我在他们的令牌上附加了以下有效负载:
const payload = {
id: user.id,
name: user.name,
permissions: user.permissions
};
该ID对应于其MongoDB文档ID,而权限则直接从其文档中获取并保存到其有效负载令牌中。它们明确规定了用户可以访问的路由。
然后,我按照以下步骤设置护照:
passport.use(
new JwtStrategy(opts, (jwt_payload, done) => {
if (!userCache[jwt_payload.id])
User.findById(jwt_payload.id)
.then(user => {
if (user) {
userCache[jwt_payload.id] = user;
setTimeout(() => {
delete userCache[jwt_payload.id]
}, 60 * 60 * 1000);//make sure data is up to date by the hour
return done(null, user);
}
return done(null, false);
})
.catch(err => {
console.log(err)
});
else done(null, userCache[jwt_payload.id]);
})
);
不用担心我的缓存系统,我计划对其进行改进,以在对用户模型进行更改时自动更新。
我的问题是,在这种方法中,护照允许我们实施,无法检查正在访问的实际路线。 jwt_payload
包含我之前设置的权限数组,但是它无用,因为我无法检查路由以确保用户得到授权。这是我当前授权路线的方式:
app.get('/api/online', passport.authenticate('jwt', {session: false}), (req, res) => {//fetch the current amount of people online
res.setHeader('Content-Type', 'text/plain');
res.send(userServer.connectionCount.toString());
});
这很好用,因为登录的每个人都应该可以访问该路由,但是,如果我想使用/api/users
路由怎么办?我没有办法传递一个特殊的字符串来表示“只有经过x
许可的用户才能使用此路由。
有什么建议吗?
我已经尝试
api.use('/api/users',(req,res,next)=>{})
,但是找到一种无需护照即可解密auth令牌的方法听起来有些多余,并增加了护照的复杂性。而且,使客户端手动通过其权限来解决前一个问题是巨大的安全风险,因为任何人都可以弥补其权限并将其附加到其请求正文中。 passport.authenticate
方法传递给路由。似乎不可能,或者我做错了事。 谢谢。