如何在 Django 中强制执行基于帐户的分离

发布于 2024-08-12 22:10:15 字数 434 浏览 6 评论 0原文

我有一个 Django 应用程序,它具有单帐户模型。我们正在将其转换为多帐户,因此几乎每个模型都会有一个 ForeignKey(Account)

确保每个帐户(每个帐户位于自己的子域中)只能访问自己的数据的最简单方法是什么?我们有一个中间件,可以填充子域以及每个请求的当前帐户。

我们可以通过在所有视图中添加 filter(...., account = request.account) 来实现这一点。这是不可取的,因为

  1. filter(...., account = request.account) 将被添加到所有查询中,从而使得此查询不干燥、重复且容易出错。
  2. 更大的风险是,如果缺少过滤器,任何地方都会存在安全风险。

I have a Django app which has a single-account model. We are converting this to be multi-account, so almost every model will have a ForeignKey(Account).

What is the easiest way to make sure that each Account (each account is in its own subdomain) can only access its own data? We have a middleware that populates the subdomain, and the current account on each request.

We can do this the hard way, by adding a filter(...., account = request.account) in all of our views. This is not desirable as,

  1. filter(...., account = request.account) will be added to all of the queries, making this non-dry, repetative and error-prone.
  2. Bigger risk is if there is a missing filter, anywhere it is security risk.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

素染倾城色 2024-08-19 22:10:16

代码段可能会为您指明正确的方向。我相信行级权限也在 1.2 的待办事项列表中,但不是 100% 确定。

This snippet might put you in the right direction. I believe row level permissions are on the todo list for 1.2 also, not 100% sure on that one though.

夜深人未静 2024-08-19 22:10:16

是否有一些重大原因导致您不能编写一个函数来自动将会话帐户插入查询并将所有其他参数作为参数?

Is there some huge reason why you can't just write a function that automatically inserts the session account into the query and takes all your other parameters as arguments?

此刻的回忆 2024-08-19 22:10:16

您正在使用 django.contrib.auth 吗?

如果是,只需将 Account 设置为 ForeignKey(User, unique=true) 并将所有模型指向 User

即。 ForeignKey(User)

另外,看看 django Auth Docs

编辑:我想我现在更好地理解你的担忧了......

而不是

my_model.objects.filter(user=request.user)

仅仅这样做:

request.user.my_model_set.all()

Are you using django.contrib.auth?

If you are, just make Account a ForeignKey(User, unique=true) and point all your models at User

ie. ForeignKey(User)

Also, Take a look at the django Auth Docs

edit: I think I understand your concern a little better now...

Instead of doing

my_model.objects.filter(user=request.user)

just do:

request.user.my_model_set.all()
知你几分 2024-08-19 22:10:15

我认为没有任何明显的赢家,特别是如果您认为并非所有查询都需要按帐户进行过滤。还要考虑旧的 threadlocals 技巧被认为是不可靠的,这意味着自动插入过滤器参数的唯一方法是使用中间件,我猜......但这对我来说似乎也是不可靠和复杂的。

我还没有想出一个好的方法来制作一个可以在这里提供帮助的查询管理器,但它可能是可能的。

因此,我认为“多租户”数据库的最佳解决方案就是确保所有查询都按帐户过滤。您可以使用:

  • 调试模式中间件,例如中间件:记录所有权筛选器

  • 在您的测试检查任何测试生成的 sql 并验证查询中是否包含帐户字段。您还可以在测试装置中包含“其他帐户”数据,您的测试将确保这些数据不会出现在任何查询结果中。

  • 确保在代码审查期间检查所有查询的过滤器

当然不太好,但这是迄今为止我能做的最好的事情。

I don't think there is any clear winner, especially if you consider that not all queries will need to be filtered by account. Also consider the old threadlocals trick is considered unreliable which means the only way to do automatic insertion of filter parameters would be with middleware I guess... but that also seems unreliable and complex to me.

I also haven't come up with a good way to make a query manager that can help here, but it might be possible.

So, I think the best solution for a "multi-tenant" database is just to make sure all your queries are filtered by account. You can do this with:

  • Debug mode middleware such as Middleware: Record ownership screener

  • In your tests check the sql generated by any tests and verify the account field is in the query. You could also include "other account" data in your test fixtures that your test would make sure do not show up in any query results.

  • Making sure all queries are checked for the filter during code review

Certainly not pretty, but the best I've been able to do so far.

大姐,你呐 2024-08-19 22:10:15

哇,我遇到了完全相同的问题。这是我得到的最佳答案:

Django:如何组织这一大模型/管理器/设计混乱?

Wow, I'm having the exact same problem. Here's the best answer I got:

Django: How would one organize this big model / manager / design mess?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文