gpt4 book ai didi

asp.net-core - ASP .NET Core web api 在中间件中设置 cookie

转载 作者:行者123 更新时间:2023-12-03 18:34:59 25 4
gpt4 key购买 nike

我正在尝试在执行操作后设置 cookie,但正在努力使其正常工作。如果我从 Controller 而不是从中间件设置它,我设法看到了 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 行它停止执行,所以有什么事情发生了我无法弄清楚。
这是我的 Startup 类(class)
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);
}
}
}

关于asp.net-core - ASP .NET Core web api 在中间件中设置 cookie,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56474696/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com