在Abp(.NetCore)开发过程中遇到很多问题,今天记录下Abp的防CSRF功能(AntiForgeryToken ),
背景知识。
AntiForgeryToken 可以说是处理/预防CSRF的一种处理方案。
那么什么是CSRF?
CSRF(Cross-site request forgery)是跨站请求伪造,也被称为One Click Attack或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。
简单理解的话就是:有人盗用了你的身份,并且用你的名义发送恶意请求。
最近几年,CSRF处于不温不火的地位,但是还是要对这个小心防范!
ABP默认开启了防CSRF的功能,具体参见 Startup 类,
但后来发现,即使在表单中不添加@Html.AntiForgeryToken() 也可以请求成功,例如
1.$.ajax 在 使用 jQuery.ajax 时不用设置 @Html.AntiForgeryToken()
注意 在请求Controller的POST方法时,需要使 contentType = 'application/x-www-form-urlencoded',这应该是.NetCore的奇怪特性。如果contentType = ‘application/json’,那么在Controller的方法中应该设置[FormBody]
如果不这么做,后台是接收不到值的。
2.abp.ajax()方法,abp.ajax以一个对象作为接收选项。你可以传递任何在jQuery的$.ajax方法中的参数。 默认值:dataType:‘json’,type:‘POST’,contentType:‘application/json’,
在 使用 abp.ajax 时也可以不用设置 @Html.AntiForgeryToken()
这是为什么呢? 原来abp.js在我们请求时自动为我们的请求头添加了RequestVerificationToken,其名称为 “X-XSRF-TOKEN”
查看ABP的源码,在AbpAntiForgeryConfiguration中设置了这个名字
并且在AbpAspNetCoreModule中自定义了RequestVerificationToken的名字为“X-XSRF-TOKEN”。
当然 token值的获取在AbpAspNetCoreAntiForgeryManager中,源码如下。
然后给IAbpAntiForgeryManager添加了一个扩展方法:SetCookie
最终,在我们的 Account/_Layout.cshtml 和 Shared\_Layout.cshtml 中调用此方法:
这也是为什么在项目测试阶段,如果跳过Account/_Layout.cshtml 和 Shared\_Layout.cshtml 步骤之后的请求都不会成功(只报400错误)的原因。
那为什么用abp.ajax 或者 $.ajax时不用设置 @Html.AntiForgeryToken()呢?
接下来来看看abp.js
在 abp.jquery.js中,
ajaxSend() 方法在 AJAX 请求开始时执行函数。它是一个 Ajax 事件。
这就是一整套ABP的AntiForgeryToken获取和验证体系。