node.js - API设计: should user ids be in url when the api is authenticated?

标签 node.js api

当正在处理的数据与调用 API 的用户相关时,需要身份验证的 API 应该在 url 调用中包含用户 ID?

想象一个 Web 应用程序正在使用的 API(两者都在同一个堆栈中) 并且它使用身份验证方法(cookie、基本身份验证等)。

假设网络管理用户拥有的书籍。 当网络应用调用/users/:id_user/books 时,会列出属于 :id_user 的图书。

在这种情况下,当处理请求时,应用程序知道用户 ID。例如,在使用 Express 和 Passport 的 Node.js 中,用户 ID 位于 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 的回答建议使用“me”作为参数,我一直在尝试执行从 req.params.id = "me"到 req.params.id = req.user 的更改.id 在一个地方,而不是在每条路由中编写代码行。 此外,也不可能在中间件中修改 req.params (它目前不存在),也不可能在作为 app.get/app.put/etc 的第二个参数传递的回调中修改。当调用该方法时,req.params.id 又是“me”,在执行数据库操作时显然失败了。

我找到的解决方案是这样的:

在你的路由文件中添加一个像这样的函数:

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.

最佳答案

好问题。 我认为解决方案之一更加干净。 在某些情况下,您需要指定谁实际上在调用该服务,因为它是共享方法(例如,您可以使用相同的方法来访问其他用户的公共(public)数据),它可能是针对登录用户或其他人,我们通常使用相同的想法,正如您所说的 "/method/:id/books" 但当 :id 等于“me”(“/users/me/books”)时,我们假设这是当前用户,我们使用护照在请求中保存的值,如果不是,则 :id 参数是我们继续该过程所需的。

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();
}

关于node.js - API设计: should user ids be in url when the api is authenticated?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18284112/

相关文章:

javascript - 使用 NodeJS 运行 Angular 2 应用程序,同时进行实时重新打包

Node.js 来自 2 个不同脚本的全局变量会发生冲突吗?

node.js - $filter 然后 $project 处理聚合请求 mongodb

node.js - 使用 Angular 为 6 的 Node 路径模块

ios - 使用 Apple Music API 创建播放列表?

asp.net - 使用没有 API key 的谷歌地图?

api - 从 Google 自定义搜索 API 获取日期

python - 解析 HTML 并保留原始内容

javascript - SoundCloud JS API - 我可以使用同一帐户登录每个人吗?

python - 使用 Python 对 Power BI REST API 进行身份验证时出现问题