.NET CORE API 与 Angular 4 - cookie 令牌和请求令牌已交换
.NET CORE API with Angular 4 - The cookie token and the request token were swapped
我在尝试使用 Angular 和 .NET CORE 实现 XSRF 时不断收到此消息:"Validation of the provided antiforgery token failed. The cookie token and the request token were swapped." 我在 Angular 和API。有人有什么想法吗?
进程
Angular 初始调用此 API 方法来检索 cookie
[HttpGet("startSession")]
public async Task<IActionResult> StartSession()
{
AntiforgeryTokenSet tokens = this.antiForgery.GetAndStoreTokens(this.HttpContext);
this.HttpContext.Response.Cookies.Append(this.options.Value.Cookie.Name, tokens.RequestToken, new CookieOptions { HttpOnly = false });
return this.Ok(
new
{
Success = true
});
}
Angular 然后拦截下一个 POST 请求并略微覆盖默认的 XSRF 处理,因为我需要它来处理 HTTPS URL
// Override default Angular XSRF handling since it won't work for
absolute URLs and we have to prefix with "https://"
// Source:https://github.com/angular/angular/blob/master/packages/common/http/src/xsrf.ts
@Injectable()
export class HchbHttpXsrfInterceptor implements HttpInterceptor {
constructor(
private tokenService: HttpXsrfTokenExtractor) {}
intercept(req: HttpRequest<any>, next: HttpHandler):
Observable<HttpEvent<any>> {
const headerName = 'X-XSRF-TOKEN';
const lcUrl = req.url.toLowerCase();
// Skip both non-mutating requests.
// Non-mutating requests don't require a token
// anyway as the cookie set
// on our origin is not the same as the token expected by another origin.
if (req.method === 'GET' || req.method === 'HEAD' ) {
return next.handle(req);
}
const token = this.tokenService.getToken();
// Be careful not to overwrite an existing header of the same name.
if (token !== null && !req.headers.has(headerName)) {
req = req.clone({headers: req.headers.set(headerName, token)});
}
return next.handle(req);
}
}
我遇到了同样的问题,我想我找到了问题所在。
AddAntiforgery
中的 options.Cookie.Name
必须与您使用 context.Response.Cookies.Append
.
手动设置的 cookie 不同
尝试更改其中之一的名称,它会起作用。现在,您使用 tokens.RequestToken
值覆盖使用 options.Cookie.Name
名称的生成的 cookie。
您可以注意到开发人员工具中的差异。
- 使用
options.Cookie.Name
生成的默认令牌标记为 http only
(HttpOnly = true
)
- 使用
context.Response.Cookies.Append
手动附加的标记被标记为HttpOnly = false
第二个是从 JS/Angular 读取的(您可以在 JS 中读取它,因为 HttpOnly=false
并在您的 ajax 请求中作为 header 发送并针对默认的无法从JS读取)
我在尝试使用 Angular 和 .NET CORE 实现 XSRF 时不断收到此消息:"Validation of the provided antiforgery token failed. The cookie token and the request token were swapped." 我在 Angular 和API。有人有什么想法吗?
进程
Angular 初始调用此 API 方法来检索 cookie
[HttpGet("startSession")]
public async Task<IActionResult> StartSession()
{
AntiforgeryTokenSet tokens = this.antiForgery.GetAndStoreTokens(this.HttpContext);
this.HttpContext.Response.Cookies.Append(this.options.Value.Cookie.Name, tokens.RequestToken, new CookieOptions { HttpOnly = false });
return this.Ok(
new
{
Success = true
});
}
Angular 然后拦截下一个 POST 请求并略微覆盖默认的 XSRF 处理,因为我需要它来处理 HTTPS URL
// Override default Angular XSRF handling since it won't work for
absolute URLs and we have to prefix with "https://"
// Source:https://github.com/angular/angular/blob/master/packages/common/http/src/xsrf.ts
@Injectable()
export class HchbHttpXsrfInterceptor implements HttpInterceptor {
constructor(
private tokenService: HttpXsrfTokenExtractor) {}
intercept(req: HttpRequest<any>, next: HttpHandler):
Observable<HttpEvent<any>> {
const headerName = 'X-XSRF-TOKEN';
const lcUrl = req.url.toLowerCase();
// Skip both non-mutating requests.
// Non-mutating requests don't require a token
// anyway as the cookie set
// on our origin is not the same as the token expected by another origin.
if (req.method === 'GET' || req.method === 'HEAD' ) {
return next.handle(req);
}
const token = this.tokenService.getToken();
// Be careful not to overwrite an existing header of the same name.
if (token !== null && !req.headers.has(headerName)) {
req = req.clone({headers: req.headers.set(headerName, token)});
}
return next.handle(req);
}
}
我遇到了同样的问题,我想我找到了问题所在。
AddAntiforgery
中的 options.Cookie.Name
必须与您使用 context.Response.Cookies.Append
.
尝试更改其中之一的名称,它会起作用。现在,您使用 tokens.RequestToken
值覆盖使用 options.Cookie.Name
名称的生成的 cookie。
您可以注意到开发人员工具中的差异。
- 使用
options.Cookie.Name
生成的默认令牌标记为http only
(HttpOnly = true
) - 使用
context.Response.Cookies.Append
手动附加的标记被标记为HttpOnly = false
第二个是从 JS/Angular 读取的(您可以在 JS 中读取它,因为 HttpOnly=false
并在您的 ajax 请求中作为 header 发送并针对默认的无法从JS读取)