I simply want to save cookies containing security tokens, but they are not persisted in the browser. Here is my AuthController
method for saving the cookie (simplified):
[AllowAnonymous]
[HttpPost("authorize")]
[ProducesResponseType((int)HttpStatusCode.OK)]
public async Task<IActionResult> AuthorizeAsync()
{
//generating access token ommited for brevity
SetTokenCookie(accessToken);
return Ok(userIdentity);
}
And SetTokenCookie
method:
private void SetTokenCookie(string accessToken)
{
var options = _jwtOptions.AccessToken;
var cookieOptions = new CookieOptions()
{
HttpOnly = true,
IsEssential = true,
Secure = false,
SameSite = SameSiteMode.Strict,
Domain = options.Issuer, //http://localhost:3394 by default
Expires = DateTime.UtcNow.AddDays(14)
};
Response.Cookies.Append(options.Name, accessToken, cookieOptions);
}
Now when I analyze the response from my Api, I see that Set-Cookie
header and token itself are fine:
Decoded token:
{
"id": "70132f61-4d83-4772-9685-7a77a9204685",
"name": "admin",
"email": "[email protected]",
"role": "Administrator",
"persist": "True",
"nbf": 1646336045,
"exp": 1646336945,
"iat": 1646336045,
"iss": "http://localhost:3394",
"aud": [
"blog.webgateway",
"blog.blogging",
"blog.comments",
"blog.users"
]
}
But when I check the cookies, nothing is saved.
I know that there are many topics related to this issue, but I already ran out of ideas I could find online:
- I wiped storage in my browser for localhost
- I added custom entry in my hosts file and changed cookie domain accordingly
- I tried setting cookie domain = null or different path
- I added Cors and allowed credentials, any methods, any headers, any origin
- I tried more permissive settings in my browser
- I tried changing cookie options (
HttpOnly
,Secure
,SameSite
) - I removed
UseHttpsRedirection()
from myStartup.cs
and made sure I connet viaHTTP
Nothing seems to work. I'm using Firefox 97.0.1. Do you know what else I could try?
CodePudding user response:
Did you try to change the Domain
to localhost
?
Per my test, using `` didn't work for me, and then I found that other cookies showed they belong to domain localhost
, so I use localhost instead, then I can see the newly created cookie. I test to call the api by tools in chrome, so I think it should be similar to your scenario.
public string saveCookie() {
var cookieOptions = new CookieOptions()
{
HttpOnly = true,
IsEssential = true,
Secure = false,
SameSite = SameSiteMode.Strict,
Domain = "localhost", //using https://localhost:44340/ here doesn't work
Expires = DateTime.UtcNow.AddDays(14)
};
Response.Cookies.Append("testCookie", "Cookie content", cookieOptions);
return "hello world";
}
CodePudding user response:
I've finally managed to solve the issue... Here are the steps I've made:
- Changed the controller method to
HttpGet
, so it just looks like this now:
[AllowAnonymous]
[HttpGet("authorize")] // <-- notice the difference
[ProducesResponseType((int)HttpStatusCode.OK)]
public async Task<IActionResult> AuthorizeAsync()
{
//generating access token ommited for brevity
SetTokenCookie(accessToken);
return Ok(userIdentity);
}
For some reason calling a Post request directly from the browser (Firefox at least in my case) doesn't seem to work for setting the cookies, even if the response looks fine, but when I changed it to Get method and accessed in a standard way (URL) it works. I will have to double-check if Post method works from the client (JavaScript).
- Apply above solution from Tiny Wang, which means changing the cookie domain to
localhost
. Having the full URL indeed prevent cookie from being saved.