背景#
現代的 ASP.NET Core 應用程式預設啟用了 Anti Forgery Token 驗證。
啟動一個 ABP 的 Web 應用程式,再透過 nginx 反向代理並配置了 SSL。
在頁面上產生的 ajax post 請求直接就報錯了,響應 302 重定向到 Error 頁面:
問題排查#
然後發現使用 jQuery 封裝的 ajax
或者 ABP 的 Dynamic JavaScript API Client Proxies 發出 ajax
請求,應用程式啟動的控制台都會提示:
[11:18:11 WRN] The required antiforgery request token was not provided in either form field "__RequestVerificationToken" or header value "RequestVerificationToken".
並且會發現 ajax 請求響應 302 重定向到了 Error 頁面提示 400 錯誤。
控制台的提示說得很清楚了,沒有在表單或請求頭中傳遞 token 值,那麼我們需要知道 token 值是從哪獲取的,通過查看原始碼,找到獲取的方式:
abp.utils.getCookieValue(abp.security.antiForgery.tokenCookieName)
也就是獲取 cookie 中鍵為 'XSRF-TOKEN'
的值,但是通過在控制台執行,發現獲取到的值為 null
,但是在瀏覽器的 cookie 表格中又能看到 'XSRF-TOKEN'
,不過將滑鼠移上去會提示:
簡單說就是這個 cookie 雖然被設置了,但是存在 Secure 問題,被瀏覽器阻止了,就相當於沒有設置,所以 js 中就拿不到值,拿不到值,發出的 ajax 請求就沒有攜帶 token 值,那 abp 服務端驗證 token 值當然就會失敗,也就直接重定向到錯誤頁面了。
解決方案#
打開 Web 專案的 ?WebModule
檔案,在其中添加如下程式碼:
public override void ConfigureServices(ServiceConfigurationContext context)
{
ConfigureAntiForgery();
}
private void ConfigureAntiForgery()
{
Configure<AbpAntiForgeryOptions>(options =>
{
options.TokenCookie.SecurePolicy = CookieSecurePolicy.Always;
});
}