【问题标题】:Include cookie from response headers in request headers在请求标头中包含来自响应标头的 cookie
【发布时间】:2019-09-27 11:22:19
【问题描述】:

我在 Traefik 反向代理后面运行多个 .NET Core 应用程序实例。当用户访问网站时,Traefik 会发回 StickyCookie(在 Set-Cookie 中):

它告诉客户端 Traefik 背后的哪个服务器接受了他的请求。如果我们想再次向同一个服务器发送请求,我们还必须在请求中包含 cookie。

如何在 .NET Core 中实现中间件,将 StickyCookie 字段附加到每个请求?它应该包含与从之前的响应中收到的相同的 StickyCookie。

基本上,我想实现与以下 Linux 命令相同的功能:

curl -v --cookie "StickyCookie=http://10.0.2.75:80" http://example.com:5000

【问题讨论】:

    标签: c# asp.net-core cookies asp.net-core-2.1 traefik


    【解决方案1】:

    可以注册中间件以在响应标头中发送任何内容。可以在startup.cs文件的Configure方法中注册中间件:

      app.UseMiddleware<CustomHeader>();
    

    然后您的 CustomHeader 类可以是

    using Microsoft.AspNetCore.Http;
    using Microsoft.Extensions.Options;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    
    namespace PEG.Api.Middleware
    {
        public class CustomHeader
        {
            private readonly RequestDelegate _next;
    
            public CustomHeader(RequestDelegate next)
            {
                _next = next;
            }
    
            public async Task Invoke(HttpContext context)
            {
                //you can add your stickyCookie in the dictionary
                var dictionary = new Dictionary<string, string[]>()
                {
                    /* add your sticky cookie here. An example below
                     {
                        "Access-Control-Allow-Credentials",new string[]{"true" }
                    }*/
                };
    
                //To add Headers AFTER everything you need to do this
                context.Response.OnStarting(state => {
                    var httpContext = (HttpContext)state;
                    foreach (var item in dictionary)
                    {
                        httpContext.Response.Headers.Add(item.Key, item.Value);
                    }
                    return Task.FromResult(0);
                }, context);
    
                await _next(context);
            }
        }
    }
    

    【讨论】:

    • 我明白这一点。但我不知道如何将StickyCookie(我们之前从响应中收到)附加到每个客户的请求?所以工作流程是这样的:1. 客户端打开网站,2. 在响应头中发送 StickyCookie,3. 从那时起,每个请求头中都必须存在相同的 StickyCookie。
    • 您在服务器上是否有一个 Web API 驱动的 .net 核心应用程序和一个独立的客户端应用程序?
    • 不,我在客户端使用 .NET Core MVC。
    【解决方案2】:

    您可以在中间件的响应头中获取StickyCookie,然后将其保存到Session,然后您可以从会话中检索数据并将其添加到请求头中。

    public class AddHeaderMiddleware
    {
        private readonly RequestDelegate _next;
    
        public AddHeaderMiddleware(RequestDelegate next)
        {
            _next = next;
        }
    
        public async Task InvokeAsync(HttpContext context)
        {
    
            var data = context.Session.GetString("StickyCookie");
    
            context.Request.Headers.Add("StickyCookie", data);
    
            context.Response.OnStarting(state =>
            {
                var httpContext = (HttpContext)state;
                var cookies = httpContext.Response.Headers["Set-Cookie"].ToString().Split(";");
                if (cookies.Length > 0)
                {
                    foreach (var item in cookies)
                    {
                        if (item.Split("=")[0] == "StickyCookie")
                        {
                            var cookie = item.Split("=")[1];
                            httpContext.Session.SetString("StickyCookie", cookie);
                        }
                    }
                }
                return Task.FromResult(0);
            }, context);
    
            await _next(context);
        }
    }
    
    public static class AddHeaderMiddlewareExtensions
    {
        public static IApplicationBuilder UseAddHeader(
            this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<AddHeaderMiddleware>();
        }
    }
    

    在 Startup.cs 中

     public void ConfigureServices(IServiceCollection services)
        {
            services.AddDistributedMemoryCache();
    
            services.AddSession(options =>
            {
                //// Set a short timeout for easy testing.
                //options.IdleTimeout = TimeSpan.FromMinutes(10);
                //options.Cookie.HttpOnly = true;
                //// Make the session cookie essential
                options.Cookie.IsEssential = true;
            });
     }
    public void Configure(IApplicationBuilder app)
    {
         //...
         app.UseSession();
         app.UseAddHeader();
         //...
    }
    

    检查措施:

    var header = HttpContext.Request.Headers;
    

    【讨论】:

    • @Mark 你想从asp.net核心(在控制器或中间件中)发送带有cookie头的请求到你的后端服务器(可能是php服务器)吗?
    猜你喜欢
    • 2016-05-06
    • 2019-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    相关资源
    最近更新 更多