我正在开发一个 Django Web 应用程序,需要两种授权:
- 基于角色(用户不应访问其他角色的网址)
- 基于用户(同一角色的用户不应能够访问其他用户的内容)
例如,我们有一个角色称为 HOD(部门主管)。这些是他们可以访问的一些网址:
url(r'^retest/(?P<retest_id>[0-9]+)/$' , views.details, name='details' ),
url(r'^retest/(?P<retest_id>[0-9]+)/accept$' , views.accept, name='accept' ),
url(r'^retest/(?P<retest_id>[0-9]+)/request$' , views.request, name='request' ),
url(r'^retest/(?P<retest_id>[0-9]+)/accepted$' , views.accepted, name='accepted' ),
url(r'^retest/(?P<retest_id>[0-9]+)/retreq$' , views.retreq, name='retreq' )
与这些相对应的一些 Controller 功能如下:
@login_required
def details(request, retest_id):
try:
retest= Retest.objects.get(pk=retest_id)
except Retest.DoesNotExist:
raise Http404("Request does not exit")
return render(request, 'retest/details.html' , { 'retest': retest })
@login_required
def accept(request, retest_id):
retest = get_object_or_404(Retest, pk=retest_id)
# update is_hod attribute only if the request is a POST.
if request.method == 'POST':
retest.is_hod = True
retest.save(update_fields=['is_hod'])
return render(request, 'retest/details.html' , {'retest': retest})
现在,这些是我所关心并希望避免的担忧:
现在,任何人都可以查看任何重新测试请求(views.details 函数),无论角色如何。我该如何实现这个授权?通过组过滤或使用 django 中内置的权限系统?其中任何一个都意味着我必须修改每个函数(除了 HOD 之外还有其他六个用户角色)。最优雅的解决方案是什么?
更棘手的是,特定部门的 HOD 可以通过简单地输入带有另一个部门的 retest_id 的 URL 来查看其他部门的重新测试请求。这不能通过组过滤来解决。 (请注意,HOD 还具有其他具有不同模型和映射的项目)
如果要解决这个问题,我相信我必须在每个函数的开头检查 URL 中寻址的内容是否真正属于当前用户并重定向。 目前 View 中有大约 60 个功能,分布在不同的用户角色中。
在这两个级别上实现授权的最优雅的方法是什么? 我应该更改 URL 的设置方式吗?
最佳答案
我不是专家,但我个人倾向于使用内置的 django 权限系统。它将解决您的两个问题,并且您可以使用 permission_required
函数装饰器轻松实现它。
一些可能会派上用场的技巧是:如果您的 View 相似并且您希望保持干燥,则可以考虑使用基于类的 View 而不是基于函数的 View ,并且您可以在 URL 上使用装饰器模式本身(在 urls.py 中)而不是在 View 函数上。
关于python - Django - 实现授权的最佳方式(基于每个角色以及每个用户)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43923000/