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

时间:2009-12-03 12:44:24

标签: django django-queryset django-authentication

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

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

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

  1. filter(...., account = request.account)将添加到所有的查询中,使其变得非干燥,重复且容易出错。
  2. 如果过滤器丢失,则存在较大的风险,只要存在安全风险。

5 个答案:

答案 0 :(得分:2)

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

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

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

  • 调试模式中间件,例如Middleware: Record ownership screener

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

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

当然不是很漂亮,但到目前为止我能做到的最好。

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

This代码段可能会让您朝着正确的方向前进。我相信行级权限也在1.2的todo列表中,但不是100%肯定在那个。

答案 3 :(得分:0)

为什么你不能只编写一个自动将会话帐户插入查询并将所有其他参数作为参数的函数?

有一个很大的原因吗?

答案 4 :(得分:0)

您使用的是django.contrib.auth吗?

如果您是,请将帐户设为ForeignKey(User, unique=true)并将所有模型指向用户

即。 ForeignKey(User)

另外,请查看django Auth Docs

编辑:我想我现在明白你的关注点了......

而不是做

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

只是这样做:

request.user.my_model_set.all()