2012-06-27 52 views
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并将其与登录的用户,看看它们是否匹配。如果他们匹配,他有权进行编辑,否则他将被重定向。

您认为如何?任何弱点?

+0

在编辑页面的form.save()中,您需要检查用户是否有权编辑此用户。你不能让他们不要修改URL ......或者在编辑页面的页面加载时检查权限并在需要时重定向... – Tisho

+0

是的,这是一个好主意。我有一个建议。看看我更新的问题。你怎么看? – Houman

+0

为什么不简单地检查窗体视图中的权限并拒绝任何未经授权的操作,这是标准用法IMO – okm

回答

0

当你使用Django auth,始终依靠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_viewFalse,用户应该得到他的授权在尝试403和记录到日志中。

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

以Django-guardian为例,您可以简单地将公司映射到组,并且可以将表示用户公司的组的联系人映射到组和assigncan_view权限。或者,assigncan_view权限通过使用信号或芹菜任务创建联系人时公司中的所有用户。

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

0

有一些第三方应用程序,你想要做,其所谓的“行级权限”,您可以给不同的用户向特定对象不同的访问什么,“行级”来自SQL其中每个对象是行在数据库

我用django-guardian做的工作

+0

谢谢你的回答。你只是给了我一个想法。我已经更新了这个问题。 – Houman

0

在功能处理数据的保存,查看是否正在编辑的对象具有相同的ID在用户登录目前。

例如,如果所讨论的对象被称为EmailPrefs,它有一个字段称为USER_ID:

  1. 装入EmailPrefs与对象的ID被编辑
  2. 如果USER_ID不匹配对象当前用户,停止进一步的处理
  3. 修改EmailPrefs对象
  4. 保存EmailPrefs对象到数据库
+0

非常好。我认为这比我建议的想法更好。由于您不需要再将ID作为附加参数传递,并且会在幕后自动检查它。因此,在创建任何模型的任何实例时,具有user_id的附加字段应存储在该对象内。在编辑对象时,该编号必须与登录用户的编号相匹配才能继续。我的理解正确吗? – Houman

2

如果您使用Django的新class based views,例如通用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字段对应于当前登录的用户,即使是在处理请求的其余部分之前。

你可以看到在project of mine的这个现实生活中的例子。

+0

这是一个很好的解决方案,至少它对我来说无论如何都是有效的。 ;-) – Patrick