ASP.NET Core无法添加Cookie:Cookie存入NonValidated未在客户端生效
我尝试在控制器被调用时添加Cookie,但该Cookie最终存入名为“NonValidated”的属性中,并未在客户端设置。我未使用任何认证或授权功能。
控制器代码
[HttpPost] [Route("login")] public async Task<IActionResult> Login() { try { using (StreamReader reader = new StreamReader(Request.Body)) { string requestBody = await reader.ReadToEndAsync(); var pass = _configuration.GetSection("Password").Value; if (requestBody == pass) { HttpContext.Response.Cookies.Append("logged-in", "true", new CookieOptions { Expires = DateTime.UtcNow.AddDays(7), IsEssential = true }); return Ok("Login successful"); } return Unauthorized("Incorrect Password"); } } catch (Exception ex) { return BadRequest(ex.Message); } }
Razor页面调用API的代码
private async Task<bool> Login(string password) { var client = _clientFactory.CreateClient(); var content = new StringContent(password, Encoding.UTF8, "text/plain"); var response = await client.PostAsync("https://localhost:7236/api/login", content); if (response.IsSuccessStatusCode) { return true; } return false; }
使用Postman调用API时,Cookie可在响应中正确设置,但通过Razor页面调用时Cookie无法生效,请问问题出在哪里?
核心原因
你用HttpClient调用API时,API返回的Cookie只会被HttpClient本身接收,不会自动同步到浏览器的Cookie存储中。浏览器的Cookie由浏览器独立管理,HttpClient是应用内的HTTP客户端,和浏览器的Cookie池完全隔离。这就是Postman能正常获取Cookie(Postman自身管理Cookie),但浏览器中看不到Cookie的根本原因。
解决方法
方法1:直接在Razor页面操作浏览器Cookie(推荐)
既然是同一应用内的操作,无需通过API中转设置Cookie,登录验证通过后直接在Razor页面的HttpContext中添加Cookie即可,浏览器会自动保存:
private async Task<bool> Login(string password) { var client = _clientFactory.CreateClient(); var content = new StringContent(password, Encoding.UTF8, "text/plain"); var response = await client.PostAsync("https://localhost:7236/api/login", content); if (response.IsSuccessStatusCode) { // 直接在当前请求的响应中添加Cookie,浏览器会自动存储 HttpContext.Response.Cookies.Append("logged-in", "true", new CookieOptions { Expires = DateTime.UtcNow.AddDays(7), IsEssential = true }); return true; } return false; }
方法2:手动提取API响应的Cookie并写入浏览器(不推荐,冗余操作)
如果一定要通过API返回Cookie再同步到浏览器,需要从HttpResponseMessage中提取Cookie内容,再通过Razor页面的HttpContext写入浏览器:
private async Task<bool> Login(string password) { var client = _clientFactory.CreateClient(); var content = new StringContent(password, Encoding.UTF8, "text/plain"); var response = await client.PostAsync("https://localhost:7236/api/login", content); if (response.IsSuccessStatusCode) { // 提取API返回的Set-Cookie头信息 if (response.Headers.TryGetValues("Set-Cookie", out var setCookieValues)) { foreach (var cookieValue in setCookieValues) { // 解析Cookie的键值对 var cookieParts = cookieValue.Split(';')[0].Split('='); if (cookieParts.Length == 2) { HttpContext.Response.Cookies.Append(cookieParts[0], cookieParts[1], new CookieOptions { Expires = DateTime.UtcNow.AddDays(7), IsEssential = true }); } } } return true; } return false; }
关于NonValidated属性的说明
ASP.NET Core中,Request.Cookies是经过验证的Cookie集合,NonValidated则存储未经过验证的原始Cookie数据。你遇到的情况里,这个属性的出现只是因为HttpClient接收了API返回的Cookie,可能在后续请求中被带回API,但浏览器从未接收到该Cookie,因此不会在浏览器中生效。
内容的提问来源于stack exchange,提问作者ollkar

