ASP .NET Core webapi在中间件中设置cookie

2023-11-26

我试图在执行操作后设置一个 cookie,努力使其工作。如果我从控制器而不是中间件设置它,我就能看到cookie。 我已经按照配置顺序进行了操作,但什么也没有。 代码示例来自一个干净的 webapi 创建的项目,所以如果有人想玩它很简单,只需创建一个空的 webapi,添加 CookieSet 类并将 Startup 类替换为下面的类(仅添加 cookie 策略选项)

这是我的中间件

public class CookieSet
{
    private readonly RequestDelegate _next;

    public CookieSet(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        await _next.Invoke(context);
        var cookieOptions = new CookieOptions()
        {
            Path = "/",
            Expires = DateTimeOffset.UtcNow.AddHours(1),
            IsEssential = true,
            HttpOnly = false,
            Secure = false,
        };
        context.Response.Cookies.Append("test", "cookie", cookieOptions);
    }
}

我添加了 p 赋值并检查执行是否永远不会到达那里,在 Cookies.Append 行上它停止执行,所以发生了一些我无法弄清楚的事情。

这是我的启动课程

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<CookiePolicyOptions>(options =>
        {
            options.CheckConsentNeeded = context => false;
            options.MinimumSameSitePolicy = SameSiteMode.None;
            options.HttpOnly = HttpOnlyPolicy.None;
            options.Secure = CookieSecurePolicy.None;
            // you can add more options here and they will be applied to all cookies (middleware and manually created cookies)
        });

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseCookiePolicy(new CookiePolicyOptions
        {
            CheckConsentNeeded = c => false,
            HttpOnly = HttpOnlyPolicy.None,
            Secure = CookieSecurePolicy.None,
            MinimumSameSitePolicy = SameSiteMode.None,
        });

        app.UseMiddleware<CookieSet>();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseMvc();
    }
}

我已将所有选项设置为最低要求,用 chrome 和 fiddler 进行了测试,但什么也没有。


好吧,我是在自言自语,但这是为了社区......

在深入研究 AspNetCore 代码后得到了这个工作。 基本上,cookie 必须在上下文响应的回调 OnStarting 上设置。 这是实现这个技巧的中间件的代码

public class CookieSet
{
    private readonly RequestDelegate _next;
    private readonly ASessionOptions _options;
    private HttpContext _context;
    public CookieSet(RequestDelegate next, IOptions<ASessionOptions> options)
    {
        _next = next;
        _options = options.Value;
    }

    public async Task Invoke(HttpContext context)
    {
        _context = context;
        context.Response.OnStarting(OnStartingCallBack);
        await _next.Invoke(context);
    }

    private Task OnStartingCallBack()
    {
        var cookieOptions = new CookieOptions()
        {
            Path = "/",
            Expires = DateTimeOffset.UtcNow.AddHours(1),
            IsEssential = true,
            HttpOnly = false,
            Secure = false,
        };
        _context.Response.Cookies.Append("MyCookie", "TheValue", cookieOptions);
        return Task.FromResult(0);
    }
}

AspNetCore 团队为此使用了一个内部类。

检查SessionMiddleware类,部分代码如下(为了答案删除了很多东西):

public class SessionMiddleware
{
    public async Task Invoke(HttpContext context)
    {
        // Removed code here

        if (string.IsNullOrWhiteSpace(sessionKey) || sessionKey.Length != SessionKeyLength)
        {
                        // Removed code here
            var establisher = new SessionEstablisher(context, cookieValue, _options);
            tryEstablishSession = establisher.TryEstablishSession;
            isNewSessionKey = true;
        }

        // Removed code here

        try
        {
            await _next(context);
        }

        // Removed code here
    }

    //Now the inner class

    private class SessionEstablisher
    {
        private readonly HttpContext _context;
        private readonly string _cookieValue;
        private readonly SessionOptions _options;
        private bool _shouldEstablishSession;

        public SessionEstablisher(HttpContext context, string cookieValue, SessionOptions options)
        {
            _context = context;
            _cookieValue = cookieValue;
            _options = options;
            context.Response.OnStarting(OnStartingCallback, state: this);
        }

        private static Task OnStartingCallback(object state)
        {
            var establisher = (SessionEstablisher)state;
            if (establisher._shouldEstablishSession)
            {
                establisher.SetCookie();
            }
            return Task.FromResult(0);
        }

        private void SetCookie()
        {
            var cookieOptions = _options.Cookie.Build(_context);

            var response = _context.Response;
            response.Cookies.Append(_options.Cookie.Name, _cookieValue, cookieOptions);

            var responseHeaders = response.Headers;
            responseHeaders[HeaderNames.CacheControl] = "no-cache";
            responseHeaders[HeaderNames.Pragma] = "no-cache";
            responseHeaders[HeaderNames.Expires] = "-1";
        }

        // Returns true if the session has already been established, or if it still can be because the response has not been sent.
        internal bool TryEstablishSession()
        {
            return (_shouldEstablishSession |= !_context.Response.HasStarted);
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ASP .NET Core webapi在中间件中设置cookie 的相关文章

随机推荐

  • 如何在SVN中找到两个分支的共同祖先?

    想象一下 您有一棵巨大的 SVN 树 树枝遍布各处 有树干 有树枝 这些树枝有树枝 等等 那么 给定树中的两个树枝 如何找到共同的祖先 我知道你可以简单地获取完整的日志并进行比较 但是如果你的主干有 75 000 个修订 并且大多数时候你确
  • 在 SpriteKit 中移动相机

    UPDATE已添加更新的代码 其工作原理符合我的预期 请参阅下面更新的代码中的 didSimulatePhysics 方法 就我而言 我只关心在 x 轴上向左或向右移动字符 其中 x 轴上的 0 是绝对左侧 x 轴上的右侧是可配置值 苹果的
  • Set-MsmqQueueACL - 允许 - 无法按照文档使用列表?

    我正在尝试使用 Powershell v5 1 Win2k16 在 Msmq 队列上设置 ACL 但即使我遵循文档 我仍然收到错误 Get MsmqQueue Name s009 ClientsServiceBus QueueType Pr
  • 如何在服务器端获取 HTTP POST 请求正文作为 Java 字符串?

    HttpExchange 对象的 getRequestBody 方法返回一个 InputStream 正确解读 正文 还有很多工作要做 它是一个 Java 库 对象 方法 向前迈出一步并将主体 在服务器端 作为现成的 Java 字符串返回
  • 如何在没有 glDrawPixels 的情况下将缓冲区对象渲染/绘制到帧缓冲区

    根据 opengl 规范 4 0 glDrawPixels 已被弃用 对于 cuda 互操作性 似乎最好使用 opengl 缓冲区对象 替代方案可以是纹理或表面 但它们存在缓存 并发问题 因此无法用于我的 cuda 内核 我只是想创建一个
  • 为什么我们使用finally块? [复制]

    这个问题在这里已经有答案了 据我所知 以下两个代码片段都具有相同的目的 为什么有finally完全阻塞吗 Code A try Some code catch Exception handling code finally Cleanup
  • 什么是锯齿状数组?

    什么是锯齿状数组 在 C 中 任何例子以及何时应该使用它 交错数组是数组的数组 string arrays new string 5 这是五个不同字符串数组的集合 每个数组的长度都可以不同 它们也可以是相同的长度 但重点是没有保证他们就是
  • ScrollViewer 上 VerticalOffset 属性的双向绑定?

    我在 Silverlight 3 0 中有一个视图和一个视图模型 该视图包含一个标准的 ScrollViewer 其中包含动态内容 根据 ScrollViewer 中的内容 用户可能已向下滚动内容一半 然后执行导致 ScrollViewer
  • 使用 CSS @font-face 时,浏览器按什么顺序使用不同类型?

    使用时 font faceCSS 中是否记录了每种主要浏览器中适用的字体类型 以及如果缺少一种或多种字体类型 它们对不同字体类型的优先级 我尝试用谷歌搜索答案 但失败了 font face font family myfont src ur
  • 将 int 转换为 BCD 字节数组

    我想使用 BCD 将 int 转换为 byte 2 数组 所讨论的 int 将来自表示年份的 DateTime 并且必须转换为两个字节 是否有任何预制函数可以执行此操作 或者您能给我一个简单的方法来执行此操作吗 example int ye
  • AlertDialog 按钮的图像

    是否可以添加drawables到positive negative and neutralAlertDialog 的按钮 如果是 那么如何 Since onPrepareDialog已弃用 您可以使用onShowListener反而 此外
  • ForbiddenError:无效的 csrf 令牌,express js

    我试图让 csurf 工作 但似乎偶然发现了一些东西 到目前为止的代码如下所示 索引 ejs
  • T-SQL 输出子句:如何访问旧的身份 ID

    我有一个 T SQL 语句 它基本上执行插入并将一些插入的值输出到表变量以供以后处理 有没有办法让我将所选记录的旧身份 ID 存储到我的表变量中 如果我使用下面的代码 我会得到 无法绑定多部分标识符 a ID 错误 DECLARE act
  • 如何使用 ACTION_VIDEO_CAPTURE 操作对相机的意图将文件的输出设置为 mp4?

    当我使用本机应用程序相机拍摄视频时 输出文件的扩展名为 3gp 我需要使用 ACTION VIDEO CAPTURE 意图操作来意图相机 这将生成一个具有 mp4 文件扩展名的文件 我该怎么做 您可以继续尝试 dis 代码 intent n
  • Swagger PHP - 如何定义嵌套属性?

    我正在使用 Swagger PHP 大多数定义都很容易定义 但我遇到了一个特定数据块的问题 该数据块不属于单独的类 而是属于关联数组 我希望显示的 json 响应 针对此问题进行了简化 id 1 status published gps l
  • ipython %timeit“赋值前引用的局部变量‘a’”

    我正在尝试运行以下代码 但我得到了local variable a referenced before assignment a x for x in range 10 b x for x in range 10 timeit a b 该语
  • 如何重新启动 git 仓库?

    我从我的一个旧项目中获取了一个存储库 并编辑了这些文件 以便我可以将其用作新项目的 骨架 说我在这里 骨架 框架 我已经在那里编辑了存储库 我将如何使用该目录中的这些文件重新启动此存储库 什么should我已经做好了 我所做的就是拉取存储库
  • jQuery 单击处理函数不会在 DOM 加载后添加的元素上触发

    我相信我可以使用 live 来做到这一点 但该方法已被弃用 问题是这样的 我有一个点击处理函数 它应该在任何具有 myClickEl 类的元素上触发 这对于加载时文档中存在的 myClickEl 元素效果很好 但是 如果我在 DOM 加载后
  • Spring配置C3P0与Hibernate?

    我有一个 Spring JPA 应用程序 其中 Hibernate 作为 JPA 提供者 我通过以下方式在 Spring 中配置了 C3P0 数据源
  • ASP .NET Core webapi在中间件中设置cookie

    我试图在执行操作后设置一个 cookie 努力使其工作 如果我从控制器而不是中间件设置它 我就能看到cookie 我已经按照配置顺序进行了操作 但什么也没有 代码示例来自一个干净的 webapi 创建的项目 所以如果有人想玩它很简单 只需创