Angular provides a built-in support for sending requests secured with the XSRF-TOKEN header. However, it won’t add the token to absolute URLs for security reasons. One way to solve the “Invalid CSRF token found” issue is to use relative links in all mutable requests and apply a custom proxy.
Debugging missing CSRF token
First, we have to be sure that Angular really doesn’t send requests with the X-XSRF-TOKEN. In the following section I’ll show you how to debug a Spring Boot application.
Adjust debug level on security logs
In order to see more detailed logs and enable security debugging add the following line to your
As a result, after restarting the app, you’ll be able to read messages logged by the
Add a breakpoint
Now you know exactly where to set a breakpoint. In other words, add it in the
CsrfFilter::doFilterInternal method (package:
org.springframework.security.web.csrf) and verify that the
actualToken is indeed
Fix the invalid CSRF token error
When inspecting the request in the developer console you’ll see the 403 error on mutable requests because the
Headers section is missing the X-XSRF-TOKEN:
Avoid absolute urls
HttpClient handles protection against Cross-Site Request Forgery attacks by default, as we can read in the documentation:
HttpClientsupports a common mechanism used to prevent XSRF attacks. When performing HTTP requests, an interceptor reads a token from a cookie, by default
XSRF-TOKEN, and sets it as an HTTP header,
Nonetheless, we have to remember to avoid absolute paths when sending any mutable requests. The
HttpXsrfInterceptor::intercept method is documented as this:
Skip both non-mutating requests and absolute URLs.https://github.com/angular/angular/blob/ff9f4de4f1147ba9ea6d17c31442a2eedcf4e0d2/packages/common/http/src/xsrf.ts#L77
Non-mutating requests don’t require a token, and absolute URLs require special handling anyway as the cookie set on our origin is not the same as the token expected by another origin.
With that in mind, we can decide to use relative paths in our requests. Below you can find an example based on the TaskDataService class:
Configure proxy to a backend server
Now we need to divert all calls that use the
/api path to a server, that in my example project, exposes endpoints on
http://localhost:8080/api/*. In order to achieve that, we need to use the Angular proxy support. Create the following file in the
src directory of your Angular project:
Next, I’m going to configure the
$ ng serve command in my
angular.json to use the proxy file:
|Every time you update your proxy configuration rerun the |
Thanks to enabling the debug log level in my
proxy.conf.json file I can read in my logs that the target was set properly:
Another key point is to read the Angular proxy documentation thoroughly in order to learn about:
- rewriting the URL path (e.g. how to remove the
/apipart from URLS);
- using proxy for multiple entries;
- changing origin when your backend is not on
To sum up, run the
$ ng serve command and verify that the Angular app attaches the XSRF-TOKEN cookie and X-XSRF-TOKEN header to mutable requests as shown on the image below:
Learn more on debugging “Invalid CSRF token found” error
- In the long run, take some time to read more on the Security: XSRF protection subject.
- You should explore The official guide on Angular Security as well.
- Visit both the HttpClientXsrfModule documentation and HttpXsrfInterceptor code.
- The Angular 9 HttpClientXsrfModule not working issue on GitHub was a tremendous help for me when I was fixing my code.
- You can find more details about proxy in this StackOverflow response.
- I found some additional useful info under the Angular 6 does not add X-XSRF-TOKEN header to http request question on StackOverflow.
- This article serves as an addendum for the Securing your Spring Boot and Angular app with JWT #3 – Frontend post.