【问题标题】:What are best practices for authorizing and sharing API resources across accounts?跨账户授权和共享 API 资源的最佳实践是什么?
【发布时间】:2021-10-05 01:54:52
【问题描述】:

我在 Node.js、Express 和 MongoDB 中构建了一个简单的 REST API——尽管技术真的不重要,因为我更多地关注设计而不是任何东西。典型的路线如下所示:

router.get('/doc/:id', async function(req, res, next) {

  const loggedInUserId = req.session.user.id;

  const doc = await db.docs.findOne({_id:req.params.id, user:loggedInUserId});

  if (!doc) {
    return next( new Error('not found') )
  }

  return res.json(doc);

});

我知道用户是文档的所有者,因为我在文档查询中使用了登录用户的 ID。但是,如果它是共享文档,则此方法将不起作用。我需要想一个更好的方式来授权一个“团队”。

我对此的最初想法是允许“文档”的所有者通过将其添加到 teams 集合来与其他用户共享它。在这种情况下,路线可能如下所示:

router.get('/doc/:id', async function(req, res, next) {

  const loggedInUserId = req.session.user.id;

  // here I check the teams collection to see if the logged
  // in user has been given access the document.
  const hasAccess = await db.teams.exists({
    doc:res.params.id,
    users:loggedInUserId
  });

  if (!hasAccess) {
    return next( new Error('forbidden') )
  }

  const doc = await db.docs.findOne({ _id:req.params.id });

  if (!doc) {
    return next( new Error('not found') )
  }

  return res.json(doc);

});

这种方法可能适用于简单的场景,但我担心在添加其他功能(如读/写/删除访问、分页、并发控制等)时可能会变得混乱。更不用说这种方法可能会大大降低我的 API 速度,因为大多数用户将访问他们自己的资源,而不是团队的一部分。

我仍处于萌芽阶段,我希望在继续前进之前制定一个可靠的计划。这似乎是一条好路还是我错过了什么?是否有跨账户授权资源的“最佳实践”?

谢谢

【问题讨论】:

  • 我猜你的意思不是return doc。你的意思是res.json(doc) 还是对请求发送响应的东西?
  • @jfriend00,是的,当然,我会更新修复。

标签: node.js mongodb api rest api-design


【解决方案1】:

决定解决这个问题。看看我的方法,希望对你有帮助。我认为直接使用查询是一种更快的方法,而且它只是一个查询。


伪模型

users
- id
- name

teams
- id
- name
- owner_id > user_teams.id

user_teams
- id
- teams_id
- users_id > users.id

permissions
- id
- name

user_permissions
- users_id > users.id
- permissions_id > permissions.id

document_permissions
- documents_id > documents.id
- permissions_id > permissions.id

documents
- id
- file_url
- owner_id > users.id
- teams_id > teams.id nullable

相信查询

用户的文件


SELECT file_url FROM documents WHERE owner_id = <current_user_id>

Shared With Me文档

SELECT
    doc.file_url,
    p.name as access_type,
    owner.name AS owner
FROM documents doc

LEFT JOIN users owner ON doc.owner_id = owner.id
LEFT JOIN permissions p ON dp.permissions_id = p.id
LEFT JOIN document_permissions dp ON dp.documents_id = doc.id
LEFT JOIN teams t ON doc.teams_id = t.id

WHERE t.users_id = <current_user_id>

-- If the document's permission is not available for the user means it's not assigned
AND dp.permissions_id IN (
    SELECT permissions_id FROM user_permissions up
    WHERE up.users_id = <current_user_id>
)

然后可以(希望)将上面的查询翻译成您在代码中使用的任何 ORM。

【讨论】:

  • 嗯...我的观点是关系数据库,而 Mongodb 不是。对于那个很抱歉。我想您可以将权限和团队元数据存储在 document 模型中,然后在那里进行查询,但我想这不是 Mongodb 的设计目的。
  • 是的,这是我正在做的事情。因为我可以将 all 权限放在一个集合中,所以我不需要多个表和连接。我可以简单地查询teams 集合(表)并确保登录用户是其中的一部分。
  • 是的——但是你将很难维护文档的权限关系和完整性,这不是 Mongodb 的强项。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-23
  • 2015-04-11
  • 2017-02-04
  • 2020-12-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多