As indicated on the comments to my question, I found the answer to my problem. A cookie can not be sent cross-domain.
My frontend was deployed on localhost:3000
and my backend on localhost:9080
, which are considered different domains apparently. If I go to localhost:9080
(I get a white page, but that doesn't matter) and I then go to the application tab in Chrome, I find that the XSRF cookie I was looking for is stored like I was expecting all along. The cookie was available from the GET
call I executed from my front-end. The problem is that the cookie needs to be available for localhost:3000
so that Angular can make use of the cookie.
There are multiple ways you can solve this issue in your local environment.
Use a proxy
You can use a proxy to map certain url paths to your backend. This is the solution I went with.
I run my Angular application with a webpack dev server. Webpack provides an easy way to proxy certain urls to your backend. For example:
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
port: 3000,
proxy: {
'/api': 'http://localhost:9080'
}
}
The Angular application runs on localhost:3000
. Any calls to localhost:3000/api/*
. will be forwarded to localhost:9080/api/*
. So in my case I no longer perform a GET
call on localhost:9080/api/authentication/csrf
, but I call localhost:3000/api/authentication/csrf
which will then get forwarded to my backend. (I added /api
to the path in my rest controller, for those wondering.)
Deploy both applications on the same port
Using the frontend-maven-plugin you can build the frontend to its dist folder and then let maven package the dist folder along with the backend for deploy. I haven't tried this, but there are various resources that show this should be easy to do with Spring boot. So both frontend and backend would be available through localhost:9080
for example.
Use Spring Profile to disable csrf locally
You can make use of Spring @Profile
annotations to create a different configuration for local environment and the rest (test, acceptance, production). Csrf can simply be disabled for development. I do not prefer this option since I like to keep DEV and other environments the same as much as possible. It's also not a real answer to the problem statement.
Special thanks to the answer of user @dspies which helped me find the problem.