当正在处理的数据与正在调用api的用户相关时,需要身份验证的API应包含url调用中的用户ID?
想象一下Web应用程序正在使用的API(两者都在同一个堆栈中) 它使用身份验证方法(cookie,基本身份验证等)。
假设网络管理用户拥有的图书。 当网络应用程序调用/ users /:id_user / books时,会列出属于:id_user。
的书籍在这种情况下,当处理请求时,应用程序已知用户ID。例如,在使用Express和Passport的node.js中,用户标识位于request.user.id中,例如
所以我想知道这是否是一个省略的好方法:id_user作为参数,因为代码可以做类似的事情:
路线:/ users / books(获取用户帐簿)
app.get('/users', auth(), function (req, res) {
var userId: req.user.id; // Get user id from authentication data.
// Find user's books
books.find({ _owner: req.user.id}, function(err, books){return res.send(books)});
}
而不是
路由:/ users /:id_user / books(使用显式用户ID从已登录用户获取图书)
app.get('/users/:id_user', auth(), function (req, res) {
var userId = req.params.id_user; // get param from the URI
// For security reasons: prevent the user to access other user books
// by providing another user id in the url by comparing logged user credentials to
// user id from URI.
if (req.params.id !== req.user.id) { return res.send(403); // Forbidden }
// Find user's books.
books.find({ _owner: userId}, function(err, books){return res.send(books)});
}
更新:
由于Jonathan P. Diaz回答谁建议使用“我”作为参数我一直在尝试执行从req.params.id =“me”到req.params.id = req.user的更改.id在一个地方而不是在每条路线中写入代码行。 此外,在作为app.get / app.put / etc的第二个参数传递的回调中,也无法修改中间件中的req.params(它在点上不存在)。当调用该方法时,req.params.id又是“我”,它在执行数据库操作时显然失败了。
我发现的解决方案是:
在您的路线文件中添加如下函数:
var callWrapper = function(callback) {
return function(req, res) {
if (req.params && req.params.id === "me") {
req.params.id = req.user.id;
}
return callback(req, res);
}
}
然后以这种方式建立路线:
app.get('/users/:id/books', securityProtectionApi, callWrapper(user.showUserBooks));
Note: user.showUserBooks is the controller method and securityProtectionApi is a check using passport for sending unauthorized when the user is not authenticated.
答案 0 :(得分:1)
好问题。 我认为解决方案更加清洁。 在某些情况下,您需要指定实际调用服务的人,因为它是一个共享方法(例如,您可以使用相同的方法访问其他用户的公共数据),它可以是已登录用户或其他人,我们通常会使用相同的想法,就像你说“/ method /:id / books”但当:id 等于“ me < strong>“(” / users / me / books “)我们假设这是当前用户,我们使用护照上保存的值,如果没有,:id param是我们继续这个过程所需要的。
app.get "/users/:id/books", (req, res, next) ->
if req.params.id and req.params.id == "me"
req.params.id = req.user.id
修改强> 您可以使用app.use()将其添加为中间件。将其置于顶部,并可能使用更具体的参数名称以使其清楚。 Express app.use()
app.use(function(req, res, next){
if (req.params && req.params.userId === "me") {
req.params.id = req.user.id;
}
next();
}
答案 1 :(得分:0)
取决于您的安全级别,但您有选择权。风险包括:
一般来说,你有 - 身份验证(登录或匿名)和 - 授权(授权,我可以查看此页面。)
将这些参数提供给网址会打开您,然后才能完成权利检查(常见错误)。
我对它的看法是:当用户上下文很重要时,不要使用它。 (配置文件,订单,帐户列表等)而是使用会话令牌并推断服务器上的权利。