背景#
现代的 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;
});
}