带有Angular 4的.NET CORE API-cookie令牌和请求令牌已交换

带有Angular 4的.NET CORE API-cookie令牌和请求令牌已交换,angular,asp.net-core,x-xsrf-token,Angular,Asp.net Core,X Xsrf Token,在尝试使用Angular和.NET CORE实现XSRF时,我一直收到这样的消息:“验证提供的反伪造令牌失败。cookie令牌和请求令牌已交换。”我在Angular和API中配置了相同的cookie和头名称。有人有什么想法吗 过程 Angular对该API方法进行初始调用以检索cookie [HttpGet("startSession")] public async Task<IActionResult> StartSession() { An

在尝试使用Angular和.NET CORE实现XSRF时,我一直收到这样的消息:“验证提供的反伪造令牌失败。cookie令牌和请求令牌已交换。”我在Angular和API中配置了相同的cookie和头名称。有人有什么想法吗

过程

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
            });
    }
[HttpGet(“startSession”)]
公共异步任务StartSession()
{
AntiforgeryTokenSet令牌=this.antiForgery.GetAndStoreTokens(this.HttpContext);
this.HttpContext.Response.Cookies.Append(this.options.Value.Cookie.Name,tokens.RequestToken,new CookieOptions{HttpOnly=false});
把这个还给我,好吗(
新的
{
成功=正确
});
}
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);
    }
    }
//覆盖默认的角度XSRF处理,因为它不适用于
绝对URL,我们必须以“https://”作为前缀
//资料来源:https://github.com/angular/angular/blob/master/packages/common/http/src/xsrf.ts
@可注射()
导出类HchbHttpXsrfInterceptor实现HttpInterceptor{
建造师(
专用令牌服务:HttpXsrfTokenExtractor{}
拦截(请求:HttpRequest,下一步:HttpHandler):
可观察{
const headerName='X-XSRF-TOKEN';
const lcUrl=req.url.toLowerCase();
//跳过两个非变异请求。
//非变异请求不需要令牌
//不管怎样,就像饼干一样
//在我们的起源上,与另一个起源所期望的标记不同。
if(req.method=='GET'| | req.method==='HEAD'){
返回next.handle(req);
}
const token=this.tokenService.getToken();
//注意不要覆盖同名的现有标头。
if(token!==null&&!req.headers.has(headerName)){
req=req.clone({headers:req.headers.set(headerName,token)});
}
返回next.handle(req);
}
}

我遇到了同样的问题,我想我找到了问题所在。
AddAntiforgery
中的
options.Cookie.Name
必须与使用
context.Response.Cookies.Append>手动设置的Cookie不同

尝试更改其中一个的名称,它将起作用。现在,使用
tokens.RequestToken
值覆盖使用
options.cookie.Name
Name生成的cookie

您可以注意到开发人员工具中的差异

  • 使用
    options.Cookie.Name
    生成的默认令牌标记为
    http only
    HttpOnly=true
  • 使用
    context.Response.Cookies.Append
    手动附加的令牌被标记为
    HttpOnly=false

第二个是从JS/Angular读取的(您可以在JS中读取它,因为
HttpOnly=false
在ajax请求中作为头发送,并根据无法从JS读取的默认头进行验证)

抱歉,忘记更新此内容,但您的回答是正确的。我现在不在启动中设置cookie名称,一切都开始工作了!