Reputation: 3218
I have an Angular 5 app and an ASP.net core 2.0 rest api. When they are both running on localhost, my authentication works just fine. I have recently deployed the rest api on another server and suddenly I can no longer authenticate. I have CORS enabled on the server via:
app.UseCors(options =>
{
options.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin().AllowCredentials();
});
In Angular, I setup my request options:
var headers: Headers = new Headers();
headers.append('Content-Type', 'application/json')
var requestOptions = new RequestOptions({
headers: headers,
withCredentials: true,
});
Using fiddler, I watch my login POST
request and see that the Response contains:
Set-Cookie: .AspNetCore.Identity.Application=CfD...;expires=Thu, 16 Aug 2018 21:25:02 GMT; path=/; samesite=lax; httponly
However, after the redirect back to the home page, I make an api request to see if a user is logged in
var url = this.runtimeConfig.getConfig().apiUrl + `api/Auth/IsUserLoggedIn/`;
return this.http.get(url, requestOptions).toPromise().then(response => {
return <BoolDTO>ServerMessages.deserialize(response);
});
Looking at fiddler, this GET
request does not contain a COOKIE header as it did when both apps were on localhost.
Odder still, if I then paste the url http://<serverip>:<port>/api/Auth/IsUserLoggedIn/
into my browser's address bar, it does send the COOKIE
header and says that a user is logged in.
Is there something I need to do to get Angular's http client to store and resend the cookie?
Upvotes: 3
Views: 1749
Reputation: 3218
It looks like it was the samesite=lax
setting on the cookie. It seems odd that "lax" would restrict this scenario, but the documentation for ASP.net's SameSiteMode.LAX says:
LAX - The cookie will be sent with "same-site" requests, and with "cross-site" top level navigation.
Since XHR requests are not top level navigation, it would not send the cookie. The solution to this is to remove the SameSite from the cookie on the server in ConfigureServices
services.ConfigureApplicationCookie(options =>
{
options.Cookie.SameSite = SameSiteMode.None;
});
I should mention that doing this opens your site to CSRF attacks, but if you want a client side frontend hosted on a different server than a REST API, this seems to be the only way. I will likely re-work my project so that the front and back end are hosted on the same server.
Upvotes: 1