While developing a SPA (React) which communicates with a ASP.Net Core API (both on localhost) the cookie will be set after a successfull login. But when deploying both applications under the same IIS (version 10) the API sets the cookie inside the login-resonse but the browser does not add the cookie for further requests. The React application runs as well as the API runs over HTTPS with a signed certificate.
I use ASP Net Identity as authentication-mechanism.
services.ConfigureApplicationCookie(config =>
{
config.Cookie.Name = "my-simple-cookie";
config.Cookie.HttpOnly = false;
config.ExpireTimeSpan = TimeSpan.FromDays(14);
config.Cookie.SameSite = SameSiteMode.None;
config.Cookie.SecurePolicy = CookieSecurePolicy.Always;
config.SlidingExpiration = false;
});
As you can see the client receives the set cookie
inside the response-header but the browser doesnt set it in productive.
Furthermore I am wondering why the browser does a pre-flight before sending the login-request which does not happen when running on localhost.
Thanks for your help!
CodePudding user response:
When you run your spa project, you can access https://...:44354
and https://...:3000
. They are like two different application. So we need to share cookies in both sites.
You can refer this answer and share the cookie.
1. Sharing Cookies Between Two ASP.NET Core Applications
Related Post:
Cookies are not set in browser in SPA to API communication
CodePudding user response:
So I figured out what the problem was: When running in localhost/development environment doing api calls with Axios includes the "withCredentials" flag automatically. But when running on productive you need to add the flag explicitly.
Which means changing
axios
.post(resultingUrl, parameters)
.then((response: AxiosResponse) => {
if (callbackFn) {
if (response.data) {
callbackFn(response.data as Z);
} else {
callbackFn();
}
}
})
.catch((error: AxiosError) => {
if (errorCallbackFn) {
errorCallbackFn(error.message);
}
});
to
axios
.post(resultingUrl, parameters, { withCredentials: true })
.then((response: AxiosResponse) => {
if (callbackFn) {
if (response.data) {
callbackFn(response.data as Z);
} else {
callbackFn();
}
}
})
.catch((error: AxiosError) => {
if (errorCallbackFn) {
errorCallbackFn(error.message);
}
});
This solved my whole problem!