我正在尝试使用带有Express的Node.js构建RESTful API。我是MEAN堆栈的新手,并希望使用最佳实践。我在掌握和实施方面遇到的问题如下:
限制用户对象上的PUT和DELETE等路由,仅允许来自“拥有”此对象的用户的请求。
我想到的一种可能性:
因此,在创建用户时,我会为其分配一个令牌,将其存储在数据库中并将其附加到会话数据中。
然后我的中间件看起来像:
router.put('/api/users/:user_id', function(req, res, next) {
// already unclear how this token should be transfered
var token = req.headers['x-access-token'] || req.session.token;
// update user (PUT /api/users/:user_id)
User.findById(req.params.user_id, function(err, user) {
if (err) {
res.send(err);
} else if (user.token != token) {
res.json({ sucess: false, message: 'User not same as authenticated user.' });
} else {
// set new information only if present in request
if (req.body.name) user.name = req.body.name;
if (req.body.username) user.username = req.body.username;
...
// save user
user.save(function(err) {
if (err) res.send(err);
// return message
res.json({ message: 'User updated.' });
});
}
});
对我来说这是一个学习项目,我知道像Passport.js这样的库。我想先学习基础知识。
如果你需要查看我正在使用的一些代码,我有一个这个项目的回购:https://github.com/messerli90/node-api-ownership
修改
我会接受一个很好的RESTful API书籍推荐,其中涵盖了这些要点,作为答案。
修改2
我实际上在本教程中找到了很多我想要的答案:http://scottksmith.com/blog/2014/05/29/beer-locker-building-a-restful-api-with-node-passport/
我试图在不使用passport.js的情况下这样做,但文章中提到的很多概念使得授权API的一些机制对我来说很清楚。
答案 0 :(得分:1)
如果我理解你的问题,这是一个API,客户端(不是浏览器)在请求中在标头中传递秘密令牌(api密钥)。似乎合理。当然,您必须要求https来保护api密钥。而且,您应该有办法让用户撤销/重新生成他们的API密钥。
到目前为止,我认为您不需要在会话中存储任何内容。似乎在会话中存储令牌只会使事情复杂化。据推测,如果要建立会话,客户端必须在第一个请求中包含令牌。那么,为什么不在每个请求上都要求它而忘记会话呢?我认为这使api客户端的生活更简单。
答案 1 :(得分:1)
'有点'太晚了,但如果有人还在寻找答案,我就是这样做的:
router.put('/', function(req, res) {
var token = req.headers['x-access-token'];
if (!token) return res.status(401).send({auth:false, message:'No token provided'});
jwt.verify (token, process.env.SECRET, function (err, decoded) {
if(err) return res.status(500).send({auth:false, message:'failed to auth token'});
User.findByIdAndUpdate({_id: decoded.user_id}, req.body, function(err, user) {
if (err)
res.send(err);
res.json({username: user.username, email: user.email});
});
});
});
只需将存储在令牌中的用户ID传递给mongoose函数即可。这样,发送请求的用户只能用他的ID更新或删除模型。
答案 2 :(得分:0)
阅读材料: Implementing Access Control in Node.JS
找到了这篇关于如何允许用户仅删除其拥有的回复的超清晰文章。希望对您有所帮助。
对我有用的东西
.delete(requireAuth, async (req, res, next) => {
const knexInstance = req.app.get("db");
const comment = await CommentsService.getById(knexInstance, req.params.id);
if (comment === undefined) {
return res.status(404).json({
error: {
message: `Comment doesn't exist.`
},
});
}
if (comment.users_id !== req.users.id) {
return res.status(401).json({
error: {
message: `You can only delete your own comments.`
},
});
}
CommentsService.deleteComment(knexInstance, req.params.id)
.then((numRowsAffected) => {
res.status(204).end();
})
.catch(next);
})