如何限制用户访问某些特定的URL?

时间:2018-09-03 09:20:49

标签: django django-views

我创建了一个视图,该视图允许用户删除带有id的特定预订,但是我不希望除与Booking对象关联的用户以外的其他用户删除它。如何限制用户访问删除自己不拥有的预订的网址。

网址:

path('manage/', views.ManageView, name='manage'),
path('manage/delete_booking/(?P<pk>\d+)', views.delete_booking, name='delete_booking'),

视图:

@login_required
def delete_booking(request, pk):
    booking = Booking.objects.get(pk=pk)
    booking.delete()
    return redirect('manage')


@login_required
def ManageView(request):
    bookings = Booking.objects.filter(user=request.user)
    context = { 
    'user': request.user,
    'bookings': bookings
    }

    return render(request, 'timetable/manage.html', context)

模板:

<div class="w3-content">
  <div class="w3-third w3-padding w3-center">
    <h4 class="bg-color">Infomation</h4>
    <p>Student ID: {{ user.profile.student_id }}</p>
    <p>Full name: {{ user.last_name }} {{ user.first_name }}</p>
</div>
<div class="w3-two w3-padding w3-center">
    <h4 class="bg-color">Booking</h4>
    {% if not bookings.exists %}
        <p>You don't have any booking</p>
    {% else %}
    {% for booking in bookings %}
        <p>{{ booking.room }} {{ booking.date }} {{ booking.lesson.number }} <a href="{% url 'delete_booking' booking.pk %}">Delete</a></p>
    {% endfor %}
    {% endif %}
</div>

1 个答案:

答案 0 :(得分:1)

您可以在视图中添加检查,例如:

@login_required
def delete_booking(request, pk):
    booking = get_object_or_404(Booking, pk=pk, user=request.user)
    booking.delete()
    return redirect('manage')

如果找不到带有该pk的对象,或者用户不是request.user的对象,则会在这里引发404错误(找不到)。

您还可以检查:

@login_required
def delete_booking(request, pk):
    booking = get_object_or_404(Booking, pk=pk)
    if booking.user_id != request.user.id:
        return HttpResponse('Unauthorized', status=401)
    booking.delete()
    return redirect('manage')

这将返回401错误(未经授权)。

两种方法都有其优点。例如,通过引发401,可以给出一个“提示”,表明存在一个带有此pk的对象。然后,恶意用户可能尝试通过另一种方式访问​​(查看,更改或删除)对象。另一方面,401更好地说明了问题所在:用户无法查看/更新/更改对象。前端可以提供更多信息。例如,如果某个管理员没有足够的权限来处理某个对象。

  

注意:通常只有POST,PATCH,PUT和DELETE方法才有副作用。因此,您可能也想省略request.method == 'GET'情况。诸如搜索引擎之类的机器人通常会“假设” GET请求是安全的(实际上,它们应该是安全的)。因此,通过不检查方法,搜索引擎可以“触发”删除,更新等操作。