asp.net core - X-XSRF-TOKEN header not included in headers using Angular 19 - Stack Overflow

admin2025-04-24  4

In my application using Angular 19 (and ASP.NET Core 8 for the back-end), I have configured my Core module to get the XSRF cookie from the back-end on app initialization :

import { inject, NgModule, provideAppInitializer } from '@angular/core';
import { CommonModule } from '@angular/common';
import { provideHttpClient, withInterceptors, withXsrfConfiguration } from '@angular/common/http';
import { tokenInterceptor } from './interceptors/token.interceptor';
import { AuthenticationService } from './services/authentication.service';

export function appInitilizerCheckTokenValidity(): Promise<void> {
  const authService = inject(AuthenticationService);
  return authService.checkTokenValidity().then(
    _isValid => {},
    () => {}
  );
}

export function appInitilizerGetXsrfToken(): Promise<any> {
  const authService = inject(AuthenticationService);
  return authService.xsrfToken().then(
    _ => {},
    () => {}
  )
}


@NgModule({
  declarations: [],
  imports: [
    CommonModule
  ],
  providers: [
    provideAppInitializer(() => appInitilizerCheckTokenValidity()),
    provideAppInitializer(() => appInitilizerGetXsrfToken()),
    provideHttpClient(withXsrfConfiguration({cookieName: 'XSRF-TOKEN', headerName: 'X-XSRF-TOKEN'})),
  ]
})
export class CoreModule { }

The xsrfToken() API looks like this :

xsrfToken(): Promise<any> {
    let url = `${this.baseXsrfUrl}/xsrf`;
    return firstValueFrom(this.http.get<{elment:any}>(url, {withCredentials: true})));
  }

And the API in my back-end looks like this :

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace AmazixWeb.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class XsrfController : ControllerBase
    {
        [HttpGet("xsrf")]
        public IActionResult XSRFToken()
        {
            var csrfToken = Guid.NewGuid().ToString();
            Response.Cookies.Append("XSRF-TOKEN", csrfToken, new CookieOptions
            {
                HttpOnly = false,
                SameSite = SameSiteMode.None,
                Secure = true
            });
            return Ok();
        }
    }
}

On initializaion the get request to collect the XSRF cookie works fine, I receive this kind of response with the xsrf token added in the cookie:

At this moment Angular should take the XSRF-TOKEN cookie and place it in every headers of a POST, PUT or DELETE request (header name : X-XSRF-TOKEN) But when I make a new POST request (a POST request to login for instance), the X-XSRF-TOKEN cookie is present, but its header is missing. See example below :

I don't know why the X-XSRF-TOKEN header is no automatically added in the POST headers. Can someone help me please ?

In my application using Angular 19 (and ASP.NET Core 8 for the back-end), I have configured my Core module to get the XSRF cookie from the back-end on app initialization :

import { inject, NgModule, provideAppInitializer } from '@angular/core';
import { CommonModule } from '@angular/common';
import { provideHttpClient, withInterceptors, withXsrfConfiguration } from '@angular/common/http';
import { tokenInterceptor } from './interceptors/token.interceptor';
import { AuthenticationService } from './services/authentication.service';

export function appInitilizerCheckTokenValidity(): Promise<void> {
  const authService = inject(AuthenticationService);
  return authService.checkTokenValidity().then(
    _isValid => {},
    () => {}
  );
}

export function appInitilizerGetXsrfToken(): Promise<any> {
  const authService = inject(AuthenticationService);
  return authService.xsrfToken().then(
    _ => {},
    () => {}
  )
}


@NgModule({
  declarations: [],
  imports: [
    CommonModule
  ],
  providers: [
    provideAppInitializer(() => appInitilizerCheckTokenValidity()),
    provideAppInitializer(() => appInitilizerGetXsrfToken()),
    provideHttpClient(withXsrfConfiguration({cookieName: 'XSRF-TOKEN', headerName: 'X-XSRF-TOKEN'})),
  ]
})
export class CoreModule { }

The xsrfToken() API looks like this :

xsrfToken(): Promise<any> {
    let url = `${this.baseXsrfUrl}/xsrf`;
    return firstValueFrom(this.http.get<{elment:any}>(url, {withCredentials: true})));
  }

And the API in my back-end looks like this :

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace AmazixWeb.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class XsrfController : ControllerBase
    {
        [HttpGet("xsrf")]
        public IActionResult XSRFToken()
        {
            var csrfToken = Guid.NewGuid().ToString();
            Response.Cookies.Append("XSRF-TOKEN", csrfToken, new CookieOptions
            {
                HttpOnly = false,
                SameSite = SameSiteMode.None,
                Secure = true
            });
            return Ok();
        }
    }
}

On initializaion the get request to collect the XSRF cookie works fine, I receive this kind of response with the xsrf token added in the cookie:

At this moment Angular should take the XSRF-TOKEN cookie and place it in every headers of a POST, PUT or DELETE request (header name : X-XSRF-TOKEN) But when I make a new POST request (a POST request to login for instance), the X-XSRF-TOKEN cookie is present, but its header is missing. See example below :

I don't know why the X-XSRF-TOKEN header is no automatically added in the POST headers. Can someone help me please ?

Share Improve this question edited Mar 10 at 8:51 Lex Li 63.5k11 gold badges124 silver badges161 bronze badges asked Jan 17 at 10:44 gallup gallupgallup gallup 715 bronze badges 2
  • How are you defining the endpoint of your POST request? As per Angular docs By default, an interceptor sends this header on all mutating requests (such as POST) to relative URLs, but not on GET/HEAD requests or on requests with an absolute URL. Note the absolute URL. So this might be the issue. Look at the default interceptor code here - you can copy-paste it and add it manually to debug it and see why the cookie does not get added. – TotallyNewb Commented Jan 17 at 16:30
  • if you want to use .NET's anti-forgery system, you should check here: learn.microsoft.com/en-us/aspnet/core/security/… (You won't need an endpoint to generate the token, and it'll be more secure than what you are doing here... it will be tied to session and form) You'd also use something like builder.Services.AddAntiforgery(options => { options.HeaderName = "X-XSRF-TOKEN"; }); (Define which header it checks against...) – browsermator Commented Jan 20 at 20:40
Add a comment  | 

1 Answer 1

Reset to default 4

Thanks to the previous comment, I've finally found the solution : moving the base url from an absolute url :

apiUrl: 'https://localhost:7139/api'

to a relative url :

apiUrl: '//localhost:7139/api'

转载请注明原文地址:http://anycun.com/QandA/1745478015a90781.html