在请求中传递模型对象ID作为参数的安全性如何



我是web开发的新手,所以情况如下:我有一个名为Qualifier的模型,它有一个名称和其他几个字段。它引用了1并且只有1个User,但没有任何其他唯一字段。例如:

class Qualifier(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
name = models.CharField(max_length=32)
other_field = models.IntegerField(default=0)

我还有一个视图,它在列表中加载属于访问用户的所有限定符对象:它们由字段User获取,因为没有其他"唯一字段"可区分。

def qualifiers_view(request):
# Access Restriction
if not request.user.is_authenticated:
return redirect("accounts:login")
# Fetch company users
qualifiers = Qualifier.objects.filter(
user=request.user
)
return render(request, 'qualifiers.html', {'qualifiers': qualifiers}) 

但这里有一个问题:在视图模板中,在该列表的每一行中,在每个限定符旁边,都有一个DELETE按钮("POST"窗体(,用于调用一个视图,该视图根据传递的参数删除同一限定符。。。但对我来说,传递用户名称作为参数似乎效率低下,因为这会导致在数据库中进行另一次搜索以找到它

我想:另一种选择是在第一次搜索时(当列表加载时(在DB中获取Qualifier对象的ID,将每个对象与自己的删除按钮相关联,并将其作为删除视图的参数,从而立即删除。

{% for q in qualifiers %}
<tr>
<td>{{q.name}}</td>
<td>
<form action="{%url 'delete_qualifier' id %}" method="POST">
{% csrf_token %}
<input type="submit" value="Delete qualifier" class='btn btn-primary'>
</form>
</td>
</tr>
{% endfor %}

但它的推荐程度如何?即使考虑到我可以拒绝视图中试图恶意抛出带有随机ID的删除请求的未授权用户。。甚至在前端放一个数据库ID是否安全?我应该坚持原来的方式吗?

我想:另一个选项是在第一次搜索时(加载列表时(在DB中获取Qualifier对象的ID,将每个对象与自己的删除按钮相关联,并将其作为删除视图的参数,从而立即删除。

按有索引的列进行搜索将显著提高效率。验证此项目是否属于用户不会花费太多额外时间,从安全角度来看,这是一个好主意。

但是,您应该验证是否允许用户删除该对象,因为否则每个人都可以删除其他人的Qualifier对象。

from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_http_methods
@login_required
@require_http_methods(["POST"])
def delete_quantifier(request, pk):
qualifiers = Qualifier.objects.filter(
pk=pk,
user_id=request.user.pk
).delete()
return redirect('accounts:login')

因此,在url中,您可以指定一个pk参数:

urlpatterns = [
# …,
path('delete/<int:pk>/', views.delete_quantifier, name='delete_quantifier'),
]

在模板中,您可以使用解析url

<form action="{%url 'delete_quantifier' pk=q.pk %}" method="POST">

注意:您可以使用@login_required装饰器[Django-doc]。

最新更新