Ettur
Ettur

Reputation: 799

ASP.NET Core 7, cookies present in browser but not saved to browser (localhost)

I went through about 100 topics regarding this issue and solutions, AND, for the life of me I cannot get a cookie saved to browser.

I have a NextJS app in the frontend, running on https://localhost:3001 ... yes HTTPS because I tried everything, including running a local ssl proxy.

My backend ASP.NET Core 7 Web API runs on IIS at localhost:55379.

Frontend request is a POST request, made with "Credentials" : "true" (tried also "include" but makes no difference) header.

Relevant settings in backend:

// Cors
builder.Services.AddCors(options =>
{
    options.AddPolicy(name: "AllowAll", policy =>
        policy
        .WithOrigins("https://localhost:3001")
        .AllowAnyMethod()
        .AllowAnyHeader()
        .AllowCredentials()
        .WithExposedHeaders("Token-Expired"));
});

Cookies are set in LogIn method of the controller

 // Set token cookies
 CookieOptions optionsToken = new()
 {
     Expires = authenticationResponse.Expiration,
     IsEssential = true,
     SameSite = SameSiteMode.None,
     Secure = true,
     HttpOnly = false,
     Domain = "localhost",                        
 };

 CookieOptions optionsRefreshToken = new()
 {
     Expires = authenticationResponse.RefreshTokenExpiration,
     IsEssential = true,
     SameSite = SameSiteMode.None,
     Secure = true,
     HttpOnly = false,
     Domain = "localhost",
 };

 Response.Cookies.Append("Bearer", JsonSerializer.Serialize(authenticationResponse.Token), optionsToken);                    
 Response.Cookies.Append("RefreshToken", JsonSerializer.Serialize(authenticationResponse.RefreshToken), optionsRefreshToken);

I tried every possible combination of SameSite, Secure, Domain, Path, HttpOnly, Secure variation under the sun.

Here is all the headers info attached to the request

GENERAL

Request URL: http://localhost:55379/api/user/Login
Request Method: POST
Status Code: 200 OK
Remote Address: [::1]:55379
Referrer Policy: strict-origin-when-cross-origin

RESPONSE

HTTP/1.1 200 OK
Cache-Control: no-cache,no-store
Pragma: no-cache
Transfer-Encoding: chunked
Content-Type: application/json; charset=utf-8
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Server: Microsoft-IIS/10.0
Set-Cookie: .AspNetCore.Identity.Application=CfDJ8PW29-... [TRUNCATED] ...Z71SFnWf1NlM; path=/; samesite=lax; httponly
Set-Cookie: Bearer=%22eyJhbGciOiJIUzI1NiIsInR5cCI6 ... [TRUNCATED] ... IkpXVCJ9.e3AeD6pKb24lmp386OoJfFQ_Z_w%22; max-age=10799; domain=localhost; path=/; secure; samesite=none
Set-Cookie: RefreshToken=%22fmP4LXNvuGooMN0%5C... [TRUNCATED] ...gkCus228QX9V%5Cu002B5rQqa7LjLzElpfTcpw%3D%3D%22; max-age=14799; domain=localhost; path=/; secure; samesite=none
Access-Control-Allow-Origin: https://localhost:3001
Access-Control-Allow-Credentials: true
X-Powered-By: ASP.NET
Date: Fri, 10 Nov 2023 19:19:28 GMT

REQUEST

POST /api/user/Login HTTP/1.1
Accept: application/json
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,fi;q=0.8,et;q=0.7
Connection: keep-alive
Content-Length: 59
Content-Type: application/json
Credentials: true
Host: localhost:55379
Origin: https://localhost:3001
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36
sec-ch-ua: "Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"

Chrome shows cookies are in response (for some reason Chrome wont show here "bearer" cookie but firefox will show that as well)

cookies response

But nothing gets saved to Application -> Cookies

empty cookies

Help!

Upvotes: 0

Views: 432

Answers (1)

Ettur
Ettur

Reputation: 799

While I dont know why cookies are not being set with CORS settings, I went a different route and placed a reverse proxy with NGINX between SPA and API, now there is no more CORS settings needed and everything just works, I have my cookies.

here are my current settings for NGINX for reference.

localhost:3000 is SPA localhost:55379 is API

server {
        listen       80;
        server_name  localhost;

        location / {
            proxy_pass http://localhost:3000;
        }

        location /api/ {
            proxy_pass http://localhost:55379;
            proxy_set_header   Host $host;
            proxy_set_header   X-Real-IP $remote_addr;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Host $server_name;
            proxy_set_header   X-Forwarded-Proto $scheme;
        }

MY GOD, how much time I spent trying to get a effin cookie.

Upvotes: 2

Related Questions