首先考虑ASP.NET Core MVC脚手架生成的以下代码片段。
// GET: Students/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if (id == null)
{
return NotFound();
}
var student = await _context.Students
.SingleOrDefaultAsync(m => m.ID == id);
if (student == null)
{
return NotFound();
}
return View(student);
}
// POST: Students/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
var student = await _context.Students.SingleOrDefaultAsync(m => m.ID == id);
_context.Students.Remove(student);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
HttpGet
和HttpPost
操作方法存在以下差异:
id
在“获取”中可以为空,但在“帖子”中不可为空。代码:
if (id == null)
{
return NotFound();
}
var student = await _context.Students
.SingleOrDefaultAsync(m => m.ID == id);
if (student == null)
{
return NotFound();
}
问题:
例如,要在GET中删除访问者请求id=5
,但稍后他会通过将id
设置为id=6
或将其设置为id=xodsfsdofsdfosdfsd
来篡改POST中的HttpPost
无效值,例如onBackPressed()
。由于SearchView
中没有初步检查,如何防止这种情况?
答案 0 :(得分:2)
您可能希望在POST操作中添加一项检查以验证用户,因为you cannot prevent tampering with the value。
删除学生的用户可能有也可能没有删除学生的权限。这取决于您的申请决定。这不是脚手架工具可以为您决定的。
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
var authorized = ValidateStudentDeletion(User, studentId: id);
if (authorized)
{
// delete student
...
return RedirectToAction("Index");
}
}
答案 1 :(得分:1)
我一直在处理这个问题很长一段时间,在审阅了一些文章之后,我的结论是:
我们假设发送的ID来自复选框或下拉列表。现在,如果用户更改了值,会发生什么:
如果要修改数据库,首先需要检查的是数据是否与用户相关联。如果没有,这里有其他情况:
用户故意篡改了ID。那么,如果是这样的话,必须阻止用户帐户,但如何?检查2号:
用户已注销并再次登录,但在其他浏览器标签中使用其他帐户。现在,发送请求的页面具有先前登录的帐户信息。
基本上,帐户信息是从身份验证Cookie中检索的,如果用户打开标签并注销并使用其他帐户登录,则需要找到一种方法来解决问题。
以下是一些建议:
如果用户退出,请使用SignalR或其他方式刷新所有浏览器选项卡。这是大多数知名公司的做法,就像Google或Facebook一样。
如果您想更轻松,请将用户名或您在身份验证Cookie中保存的任何数据哈希,并将其保存在HTML代码的隐藏字段中。然后将其与从请求中检索到的cookie的相同哈希值进行比较。如果他们确实发生冲突,请阻止用户采取任何操作并刷新页面。
我通常做的是在数据库中保存这些冲突,如果超出限制,我意识到用户是垃圾!