Controlling Django auth user access to specific object instances

回眸只為那壹抹淺笑 提交于 2019-12-02 07:03:28

问题


In my Django project, I have various users created by Django's built-in authentication system. Each user can create their own instances of the App model. I would like to restrict user access to objects such that users can only view the instances they have created. To do that I have created this view:

@login_required
def appDetail(request, app_id):
    try:
        app = App.objects.get(pk=app_id)

        # Testing if the currently logged in user is 
        # the same as the user that created the 'app':

        if request.user.id == app.user.user.id:
            if request.method == 'POST':
                form = AppForm(request.POST, instance=app)
                if form.is_valid():
                    edited_app = form.save()
                    return HttpResponseRedirect('/thanks/')
            else:
                form = AppForm(instance=app)

        # If 'app' does not belong to logged in user, redirect to 'accessdenied' page:

        else:
            return HttpResponseRedirect('/accessdenied/')
    except LeaveApp.DoesNotExist:
        raise Http404
    return render(request, 'AppDetail.html', {'form':form})

It works, but I'm wondering if there's a more commonly accepted and/or safe way to do this?


回答1:


This is called row-level permissions and it's a very common problem. See here for all the apps that solve it.

If that particular test is all you need to do, go for a custom solution like yours (though, since it's boilerplate, it's preferable to move it to a decorator). Otherwise, just use an existing app.




回答2:


I would put the form submission in a different view and write a custom decorator, which you could also use for similar issues. I would also return a 404 instead of access denied. You might not want to show users that you are protecting something.




回答3:


There is a decorator called user_passes_test that restricts access to a view based on if the user passes a certain check

from django.contrib.auth.decorators import login_required, user_passes_test

@login_required
@user_passes_test(lambda user: user.username == app.user.user.id)
MyView(request):
    ...

You can also add in an optional argument for a url to redirect to in the event they fail the check.

Trying to do this from the admin page is also pretty easy, but takes a few extra steps.

Docs Here



来源:https://stackoverflow.com/questions/16053122/controlling-django-auth-user-access-to-specific-object-instances

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!