1

抱歉,我还是 Django 的新手,希望这个问题不会不合适。

当我的模板中有以下内容时:

<td><a href="/contact/edit/?id{{ item.id }}">{{ item.last_name }}</a></td>

通过单击姓氏,用户将被重定向到以下链接以进行编辑。

http://127.0.0.1:8000/contact/edit/?id=1

但是,是什么阻止了任何登录用户在浏览器中注入不同的 id 并编辑不属于他的记录?

更新

当我阅读下面的评论和答案时,我有了一个想法。我不能只为每个用户创建一个 UserProfile 并附加一个唯一的公司范围的 uuid.uuid1(),而不是使用第三方应用程序。每次登录用户尝试编辑某些内容时,他唯一的公司 uuid 也将作为附加参数在链接中传递。

在编辑方面,它会收集这个 guid 并将其与登录用户进行比较,看看它们是否匹配。如果他们匹配,他被授权继续编辑,否则他将被重定向。

你怎么看?有什么弱点吗?

4

4 回答 4

2

如果您使用 Django 新的基于类的视图,例如通用的UpdateView,您可以扩展dispatch处理程序。

def dispatch(self, request, *args, **kwargs):
    handler = super(MyEditView, self).dispatch(request, *args, **kwargs)
    # Only allow editing if current user is owner
    if self.object.author != request.user:
        return HttpResponseForbidden(u"Can't touch this.")
    return handler

author在这种情况下,代码会在处理请求的其余部分之前验证模型对象的字段是否对应于当前登录的用户。

你可以在我的一个项目中看到一个真实的例子。

于 2012-06-27T15:41:41.517 回答
0

有一些第三方应用程序可以做你想做的事,它称为“行级权限”,您可以在其中为不同的用户授予对特定对象的不同访问权限,“行级”来自 SQL,其中每个对象都是数据库中的一行

我使用django-guardian来完成这项工作

于 2012-06-27T12:14:39.507 回答
0

在处理数据保存的函数中,检查正在编辑的对象是否与当前登录的用户具有相同的 ID。

例如,如果有问题的对象名为 EmailPrefs,并且它有一个名为 user_id 的字段:

  1. 使用正在编辑的对象的 ID 加载 EmailPrefs 对象
  2. 如果 user_id 与当前用户不匹配,则停止进一步处理
  3. 修改 EmailPrefs 对象
  4. 将 EmailPrefs 对象保存到数据库
于 2012-06-27T12:29:44.857 回答
0

当您使用 Djangoauth时,始终依赖于session识别用户的机制,而不是制作其他一些 id,例如uuid1()(例如,当您需要在电子商务站点中的额外会话时除外HTTPS)。

对于权限部分,您可以直接检查所有权,主要如Koliber Services所述。和之间Company的关系对于权限检查的逻辑至关重要。有很多方法可以对关系进行建模,因此代码会有很大差异。例如:UserContact

# a modeling way
User.company -> Company : an user belongs to a company
Contact.contributor -> User : a contact is contributed by an user, would be invalid is user is leaving the company
# could check accessibility by 
can_view = contact.contributor.company_id == current_user.company_id

# another modeling way
User.company -> Company : an user belongs to a company
Contact.company -> Company : a contact info is owned by a company, does not share globally
# could check accessibility by
can_view = contact.company_id == current_user.company_id

can_view什么时候False,用户应该因为他的未经授权的尝试而得到一个 403 并被记录。

通常,上述方法足以保护内容(在 Django Admin 中还没有)。但是,当您有许多不同类型的权限检查甚至行权限检查时,最好使用一些统一的权限 API。

以 Django-guardian 为例,您可以简单地将公司映射到组,并assign can_view允许代表用户公司的组的联系人。或者,使用信号或芹菜任务创建联系人时对公司所有用户assign的权限。can_view

此外,您可以使用/contact/1/edit/而不是/contact/edit/?id=1. 通过这种方式,该int(request.GET('id'))部分被移动到 urlconf 之类r'^contact/(?P<pk>\d+)/$'的,更少的代码,更清晰。

于 2012-06-28T13:53:38.330 回答