我创建了一个视图,该视图允许用户删除带有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>
答案 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请求是安全的(实际上,它们应该是安全的)。因此,通过不检查方法,搜索引擎可以“触发”删除,更新等操作。