我正在构建的页面很大程度上依赖于 AJAX。基本上,只有一个“页面”,并且每次数据传输都是通过 AJAX 处理的。由于浏览器端过度乐观的缓存会导致奇怪的问题(数据未重新加载),因此我必须使用 POST 执行所有请求(也读取) - 这会强制重新加载。
现在我想阻止针对CSRF的页面。通过表单提交,使用Html.AntiForgeryToken()
工作得很好,但是在 AJAX 请求中,我想我必须手动附加令牌?有什么开箱即用的东西吗?
我当前的尝试看起来像这样:
我很想重用现有的魔法。然而,HtmlHelper.GetAntiForgeryTokenAndSetCookie
是私有的,我不想在 MVC 中乱搞。另一种选择是编写一个扩展,例如
public static string PlainAntiForgeryToken(this HtmlHelper helper)
{
// extract the actual field value from the hidden input
return helper.AntiForgeryToken().DoSomeHackyStringActions();
}
这有点hacky并且留下了更大的问题未解决:如何验证该令牌?默认验证实现是内部的,并且针对使用表单字段进行了硬编码。我尝试写一个稍微修改过的ValidateAntiForgeryTokenAttribute
,但它使用了AntiForgeryDataSerializer
这是私人的,我也不想复制它。
在这一点上,提出一个自行开发的解决方案似乎更容易,但这实际上是重复的代码。
有什么建议如何以聪明的方式做到这一点?我是否遗漏了一些完全明显的东西?
您可以使用常规的Html.AntiForgeryToken()
帮助程序在页面上的某个位置(不一定在表单内)生成隐藏字段并将其包含在 ajax 请求中:
var token = $('input[name=__RequestVerificationToken]').val();
$.post(
'/SomeAction', { '__RequestVerificationToken': token },
function() {
alert('Account Deleted.');
}
);
要在服务器端验证它:
[AcceptVerbs(HttpVerbs.Post)]
[ValidateAntiForgeryToken]
public ActionResult SomeAction()
{
return View();
}
如果您的页面上有多个令牌,您可能需要指定要包含哪一个。由于现有的帮助器生成具有相同名称的隐藏字段,因此很难制作一个好的选择器,因此您可以将它们放置在跨度内:
<span id="t1"><%= Html.AntiForgeryToken() %></span>
<span id="t2"><%= Html.AntiForgeryToken() %></span>
然后选择对应的token:
var token = $('#t1 input[name=__RequestVerificationToken]').val();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)