標籤:art rtu man ken name att 網站 項目 nbsp
在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中設定了定義了TokenCookieName和TokenHeaderName。一個是token儲存在Cookie中時的名字,一個是token在要求標頭中被傳輸的名字
並且在AbpAspNetCoreModule中自訂了RequestVerificationToken的名字為“X-XSRF-TOKEN”。(這是微軟定義的另一種驗證方式,即不從表單中傳輸和擷取token值,而是從要求標頭中擷取。預設的名字是“RequestVerificationToken”當然你也可以自訂它。)
當然 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 事件。也就是說 在每個ajax請求前,abp為我們的要求標頭上加上了“X-XSRF-TOKEN”。
這就是一整套ABP的AntiForgeryToken擷取和驗證體系。
Abp(.NetCore)開發與發布過程2