问题描述
我目前有一个基本的 ASP.Net 样板。核心 3.1 项目,我托管在 IIS 上,并希望在相同的 URL 上但在不同的段上为 Angular 10 应用程序提供服务。我已经通过 HTTP 上的 Angular 和 Https 上的 API 成功实现了这一点,但在 HTTP 和 POST 或 PUT 上都存在问题。
例如
API - https://application/api
Angular 网络应用程序 - https://application/app
目前,我的 IIS 配置在主 ASP 构建目录中。在 build 目录中,我有一个 Angular 目录,在其中构建了 Angular 应用程序。
我目前的问题是,当我进行任何 POST/PUT 时,我得到 400。在日志中我得到
所需的防伪标头值“X-XSRF-TOKEN”不存在。 Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException:所需的防伪标头值“X-XSRF-TOKEN”不存在。
现在,当我看到一个成功的请求时,例如在 HTTP 上运行的 Angular 和运行 Https 的 API,上面提到的这个标头不存在。我看到的是另一个请求 (OPTIONS) 并获得 204 的状态代码。
如果我设置了属性,请求在有效载荷方面是正确的
[IgnoreAntiforgeryToken]
POST 和 PUT 成功。
更新 - 我注意到如果我导航到 Swagger,会生成一个 XSRF-TOKEN cookie。如果我删除 cookie,POST 和 PUT 就可以了,我没有问题。
我认为通过在 swagger 实现中停止 XSRF 令牌应该很容易解决,但这是否会留下潜在的安全问题?也许另一种选择是让 Angular 应用程序删除 cookie?
任何想法将不胜感激。
基思
解决方法
通过在 Angular 应用中创建 HTTP 拦截器并检查“XSRF-TOKEN”cookie,然后将标头添加到请求中解决了该问题。
import { HttpEvent,HttpHandler,HttpInterceptor,HttpRequest } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
@Injectable()
export class AddCsrfHeaderInterceptorService implements HttpInterceptor {
intercept(req: HttpRequest<any>,next: HttpHandler): Observable<HttpEvent<any>> {
const requestToken = this.getCookieValue('XSRF-TOKEN');
return next.handle(req.clone({
headers: req.headers.set('X-XSRF-TOKEN',requestToken)
}));
}
private getCookieValue(cookieName: string) {
const allCookies = decodeURIComponent(document.cookie).split('; ');
for (let i = 0; i < allCookies.length; i++) {
const cookie = allCookies[i];
if (cookie.startsWith(cookieName + '=')){
return cookie.substring(cookieName.length + 1);
}
}
return '';
}
}
通过提供者将拦截器添加到模块中:
@NgModule({ ...
providers: [
{ provide: HTTP_INTERCEPTORS,useClass: AddCsrfHeaderInterceptorService,multi: true }
]
....