ASP.NET Core 2.1 MVC - 无法设置从网络接收的 cookie api 响应
ASP.NET Core 2.1 MVC - can't able to set the cookie received from the web api response
我的 ASP.NET 基于 Core 2.1 的 MVC(客户端)应用程序使用 webapi。
客户端应用程序url:
http://testdomain.com:8458/
网络Apiurl:
http://testdomain.com:8404/
在网络上 api 设置 cookie 的操作方法如下,
public async Task<IActionResult> GetOrdersAsync(string parameter)
{
HttpContext.Response.Cookies.Append(
"cookieKey",
"cookieValue",
new Microsoft.AspNetCore.Http.CookieOptions { IsEssential = true }
);
return Ok();
}
在调用 webapi 的客户端 MVC 应用程序上,在响应中 object 我可以看到 'set-cookie' header
的存在
[Microsoft.AspNetCore.Cors.EnableCors]
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> ShowOrdersAsync(string parameter)
{
var response = await serviceClient.GetOrdersFromBackendAsync(parameter);
return Ok(response);
}
但是响应中的 cookie header,没有存储在浏览器 cookie 存储中
我错过了什么?如何在客户端应用程序浏览器中设置从 webapi 应用程序接收的 cookie?
关于 Startup.cs 包含在管道代码下方,
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddDefaultPolicy(
builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
});
});
// Add framework services.
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseCors();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=LandingPage}/{id?}");
});
}
根据您的代码和描述,我发现您尝试使用 MVC 控制器方法调用 web api 和 api return set-cookie header.
在这个动作中,MVC控制器是客户端,webapi是服务器,服务器returnset-cookieheader是MVC客户端。这部分是对的。
但是 MVC 控制器不会自动 return 这个 set cookie 到浏览器客户端,因为 MVC 是服务器并且你没有任何代码来添加 set-cookie header.
如果你想给客户端设置 cookie,我建议你可以将代码添加到 MVC 控制器而不是 web api 控制器,因为 MVC 控制器可以将 cookie 添加到客户端浏览器而不是 web api.
更多详情,您可以参考以下代码:
[Microsoft.AspNetCore.Cors.EnableCors]
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> ShowOrdersAsync(string parameter)
{
var response = await serviceClient.GetOrdersFromBackendAsync(parameter);
HttpContext.Response.Cookies.Append(
"cookieKey",
"cookieValue",
new Microsoft.AspNetCore.Http.CookieOptions { IsEssential = true }
);
return Ok(response);
}
根据您的描述,您可以先读取cookie,然后将其添加到MVC控制器响应中。
更多详情,您可以参考以下代码:
public IActionResult Index()
{
HttpClient httpClient = new HttpClient();
var re = httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Get, "https://localhost:44387/WeatherForecast")).Result;
var Cookies = ExtractCookiesFromResponse(re);
foreach (var item in Cookies)
{
HttpContext.Response.Cookies.Append(
item.Key,
item.Value,
new Microsoft.AspNetCore.Http.CookieOptions { IsEssential = true });
}
return View();
}
public static IDictionary<string, string> ExtractCookiesFromResponse(HttpResponseMessage response)
{
IDictionary<string, string> result = new Dictionary<string, string>();
IEnumerable<string> values;
if (response.Headers.TryGetValues("Set-Cookie", out values))
{
Microsoft.Net.Http.Headers.SetCookieHeaderValue.ParseList(values.ToList()).ToList().ForEach(cookie =>
{
result.Add(cookie.Name.Value, cookie.Value.Value);
});
}
return result;
}
结果:
我的 ASP.NET 基于 Core 2.1 的 MVC(客户端)应用程序使用 webapi。
客户端应用程序url: http://testdomain.com:8458/
网络Apiurl: http://testdomain.com:8404/
在网络上 api 设置 cookie 的操作方法如下,
public async Task<IActionResult> GetOrdersAsync(string parameter)
{
HttpContext.Response.Cookies.Append(
"cookieKey",
"cookieValue",
new Microsoft.AspNetCore.Http.CookieOptions { IsEssential = true }
);
return Ok();
}
在调用 webapi 的客户端 MVC 应用程序上,在响应中 object 我可以看到 'set-cookie' header
的存在 [Microsoft.AspNetCore.Cors.EnableCors]
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> ShowOrdersAsync(string parameter)
{
var response = await serviceClient.GetOrdersFromBackendAsync(parameter);
return Ok(response);
}
但是响应中的 cookie header,没有存储在浏览器 cookie 存储中
我错过了什么?如何在客户端应用程序浏览器中设置从 webapi 应用程序接收的 cookie?
关于 Startup.cs 包含在管道代码下方,
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddDefaultPolicy(
builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
});
});
// Add framework services.
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseCors();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=LandingPage}/{id?}");
});
}
根据您的代码和描述,我发现您尝试使用 MVC 控制器方法调用 web api 和 api return set-cookie header.
在这个动作中,MVC控制器是客户端,webapi是服务器,服务器returnset-cookieheader是MVC客户端。这部分是对的。
但是 MVC 控制器不会自动 return 这个 set cookie 到浏览器客户端,因为 MVC 是服务器并且你没有任何代码来添加 set-cookie header.
如果你想给客户端设置 cookie,我建议你可以将代码添加到 MVC 控制器而不是 web api 控制器,因为 MVC 控制器可以将 cookie 添加到客户端浏览器而不是 web api.
更多详情,您可以参考以下代码:
[Microsoft.AspNetCore.Cors.EnableCors]
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> ShowOrdersAsync(string parameter)
{
var response = await serviceClient.GetOrdersFromBackendAsync(parameter);
HttpContext.Response.Cookies.Append(
"cookieKey",
"cookieValue",
new Microsoft.AspNetCore.Http.CookieOptions { IsEssential = true }
);
return Ok(response);
}
根据您的描述,您可以先读取cookie,然后将其添加到MVC控制器响应中。
更多详情,您可以参考以下代码:
public IActionResult Index()
{
HttpClient httpClient = new HttpClient();
var re = httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Get, "https://localhost:44387/WeatherForecast")).Result;
var Cookies = ExtractCookiesFromResponse(re);
foreach (var item in Cookies)
{
HttpContext.Response.Cookies.Append(
item.Key,
item.Value,
new Microsoft.AspNetCore.Http.CookieOptions { IsEssential = true });
}
return View();
}
public static IDictionary<string, string> ExtractCookiesFromResponse(HttpResponseMessage response)
{
IDictionary<string, string> result = new Dictionary<string, string>();
IEnumerable<string> values;
if (response.Headers.TryGetValues("Set-Cookie", out values))
{
Microsoft.Net.Http.Headers.SetCookieHeaderValue.ParseList(values.ToList()).ToList().ForEach(cookie =>
{
result.Add(cookie.Name.Value, cookie.Value.Value);
});
}
return result;
}
结果: