3

I'm creating a proof of concept to use cookie authentication with jwt's in aspnet core with a separate UI server (i.e. the UI is hosted on localhost:4200 and the backend on localhost:5001). This repo that exhibits this and the following problem can be found here. It based off of dotnet-labs/JwtAuthDemo. No matter how hard I try, I cannot seem to get the cookie to be set in the browser tab for the UI page despite the set-cookie header being clearly seen in the response header on login. I can only get the cookie to be set when I use the swagger page for the backend (which uses same site conventions).

Note: the original repo that this is based off of uses jwt's and session storage so the app works just fine. I'm trying to get the jwt set in a cross site cookie as a proof of concept with the following line HttpContext.Response.Cookies.Append("TestCookie", jwtResult.AccessToken, cookieOptions);

The flow is as follows:

I make a login request here

this.http.post<LoginResult>(`${this.apiUrl}/login`, { username, password })

It is then intercepted here where I try to add withCredentials or any headers

request = request.clone({
    withCredentials: true
});

It is then received by the backend with the following CORS setup

services.AddCors(options =>
{
    options.AddDefaultPolicy(
        builder =>
        {
            builder
                .WithOrigins("http://localhost:4200", "https://www.local.dev")
                .AllowCredentials()
                .WithHeaders("Content-Type")
                .AllowAnyMethod();
        }
    );
});

It is then received by the following controller method where I try to set the cookie on this line

// Ommitting cookie options for brevity
HttpContext.Response.Cookies.Append("TestCookie", jwtResult.AccessToken);
// The source code doesn't have it, but I tried using various cookie options like the following
HttpContext.Response.Cookies.Append("TestCookie", jwtResult.AccessToken, new CookieOptions
{
    SameSite = SameSiteMode.None
    Secure = true
});
// and also the following among other configurations
HttpContext.Response.Cookies.Append("TestCookie", jwtResult.AccessToken, new CookieOptions
{
    SameSite = SameSiteMode.Lax
});

The response is then received by the browser exactly like the responses posted in this stack overflow question. Secifically, this is what I receive in my browser: The request comes back with the cookie as expected: successful network request But, alas, no cookie is set: empty cookie page This happens even samesite=none and secure=true: enter image description here empty cookie page When I login via the swagger page (which is same site), I get the following response: successful network request And I see the cookie is set: enter image description here It also works when samesite=none and secure=true enter image description here enter image description here

I have tried all of the common things to solve this problem that the internet, especially the stack overflow community, recommends:

  1. make sure CORS is set properly
    • I have all the proper headers set
  2. make sure samesite=lax is set or samesite=none with secure=true and https
    • Neither works for this project either
    • I have even gone as far to set up a reverse proxy on my local machine to get https on both the front end and back end (didn't work either)
  3. realize that chrome silently blocks any cross site cookies that don't have samesite=none, secure=true, and are sent over https
    • I have even tried this on firefox and I can't get it working
  4. make sure withCredentials=true or credentials='include' on the request being sent
    • I think this is just for sending cookies, not setting them, but it still doesn't work

Other solutions tried and resources consulted:

- https://stackoverflow.com/questions/46288437/set-cookies-for-cross-origin-requests
    - I am actually experiencing this exact same problem with the same symptoms, but none of the solutions are working

- https://medium.com/swlh/7-keys-to-the-mystery-of-a-missing-cookie-fdf22b012f09
- https://github.com/axios/axios/issues/1553
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
- https://stackoverflow.com/questions/50511096/set-cookie-not-working-in-chrome
- https://stackoverflow.com/questions/50369779/cookie-not-being-set-in-browser
- https://stackoverflow.com/questions/60131986/why-chrome-can-t-set-cookie
- https://stackoverflow.com/questions/6970754/why-are-my-cookies-not-setting
- https://github.com/github/fetch/issues/386
- https://stackoverflow.com/questions/1134290/cookies-on-localhost-with-explicit-domain/1188145#1188145
- https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-5.0#credentials-in-cross-origin-requests
- https://stackoverflow.com/questions/7346919/chrome-localhost-cookie-not-being-set
- https://stackoverflow.com/questions/49065174/why-does-chrome-ignore-set-cookie-header
- https://medium.com/swlh/how-the-new-chrome-80-cookie-rule-samesite-none-secure-affects-web-development-c06380220ced

Given that all of the solutions point to the same solution and its not working for me, I must have set something up incorrectly or must be missing something really obvious. Perhaps there is a silent browser feature I'm not aware of? What is the issue here?

  • In the end your question seems to be "when I send the following request (details missing) from my SPA running on localhost:4200 I get the following response (details missing) and expect the following cookie to be set on domain (missing) but it's not set". Could you please add the missing details (from browser > dev tools > network)? – Christoph Lütjen Aug 19 '21 at 12:32
  • Thanks, I updated it with more information. Is this better now? – Ryan Clements Aug 19 '21 at 12:54
  • We're all a little bit lazy and and it would really help if you add the request and response details you can see in your browser developer tools. Then we can se what you really send and receive. Also it's still not clear on which domain you expect the cookie. – Christoph Lütjen Aug 19 '21 at 13:00
  • Btw: If you get the response data in javascript and you see no error (non 2xx status code) in browsr > dev tools > network, then CORS is not a problem here. – Christoph Lütjen Aug 19 '21 at 13:02
  • Thanks, I believe I have everything including the responses received needed to debug what is happening. – Ryan Clements Aug 19 '21 at 13:06
  • I was fighting with those cookie issues too and as far as I remember, you cannot use secure=true from an insecure page (localhost:4200) - except of Firefox since version 52 which should allow it from localhost. So you could give it a try with FF if it works there, the missing encryption is the problem. (hoping s/o will give you a better answer) – Christoph Lütjen Aug 19 '21 at 13:37
  • Yeah I was hoping that it was just a localhost issue. I tried running both the front end and backend behind a reverse proxy locally so I could access the front end via something like https://www.local.dev, but alas I wasn't able to get that working. Would this rule out the localhost suggestion you made? – Ryan Clements Aug 19 '21 at 14:47
  • No. The possible problem = http instead of https for your angular app. Possible solution: Use https or firefox + http + localhost. Again: This is more guessing than knowing. – Christoph Lütjen Aug 19 '21 at 15:49

0 Answers0