【问题标题】:ASP.NET Core 2.1 MVC - can't able to set the cookie received from the web api responseASP.NET Core 2.1 MVC - 无法设置从 Web api 响应接收到的 cookie
【发布时间】:2022-01-09 06:01:17
【问题描述】:

我的基于 ASP.NET Core 2.1 的 MVC(客户端)应用程序使用 webapi。

客户端应用程序网址: http://testdomain.com:8458/

Web API 网址: http://testdomain.com:8404/

关于设置cookie的web api action方法如下,

 public async Task<IActionResult> GetOrdersAsync(string parameter)
    {
        HttpContext.Response.Cookies.Append(
                    "cookieKey",
                    "cookieValue",
                    new Microsoft.AspNetCore.Http.CookieOptions { IsEssential = true }
                );

        return Ok();           
    }

在调用 webapi 的客户端 MVC 应用程序中,在响应对象中我可以看到“set-cookie”标头的存在

    [Microsoft.AspNetCore.Cors.EnableCors]
    [HttpGet]
    [AllowAnonymous]
    public async Task<IActionResult> ShowOrdersAsync(string parameter)
    {
      var response = await serviceClient.GetOrdersFromBackendAsync(parameter);
      return Ok(response);
    }

但是响应头中的 cookie,没有被存储在浏览器的 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?}");
        });
    }

【问题讨论】:

    标签: asp.net-mvc cookies asp.net-core-webapi cross-domain asp.net-core-2.0


    【解决方案1】:

    根据您的代码和描述,我发现您尝试使用 MVC 控制器方法调用 web api 并且 api 返回 set-cookie 标头。

    在这个动作中,MVC 控制器是客户端,web api 是服务器,服务器返回 set-cookie 头给 MVC 客户端。这部分是对的。

    但 MVC 控制器不会自动将此设置的 cookie 返回给浏览器客户端,因为 MVC 是服务器,您没有任何代码来添加 set-cookie 标头。

    如果你想给客户端设置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;
        }
       
    

    结果:

    【讨论】:

    • @ Brando,在上面的示例代码中,cookie 是由 MVC 控制器设置的,但只有服务器知道 cookie 及其值,该 cookie 必须来自我的应用程序中的 webapi。有什么方法可以满足这个需求?
    • 请看我的更新
    • @ Brando,它按照您的编码方式工作,但这是推荐的设计还是有更好的设计/方法将 cookie 直接从 webapi 推送到 MVC 控制器客户端浏览器?只是好奇。谢谢。
    猜你喜欢
    • 2019-02-04
    • 2018-04-23
    • 2018-05-23
    • 2020-05-30
    • 1970-01-01
    • 2015-03-16
    • 1970-01-01
    • 2022-01-02
    • 2022-07-07
    相关资源
    最近更新 更多