我正在将Web表单应用程序转换为asp.net core mvc.在我的Web表单应用程序中,有时在我设置一些响应cookie后,其他代码需要查看它们是否已设置,如果是,请访问cookie的属性(即value,Expires,Secure,http).在webforms和MVC 5中,可以迭代cookie并返回任何特定的cookie,如此(我知道的老学校)
for(int i = 0; i < cookies.Count; i++) {
if(cookies[i].Name == cookieName) {
return cookies[i];
}
}
Run Code Online (Sandbox Code Playgroud)
但是在asp.net core mvc中访问响应cookie的界面如下所示:
基于此接口,我没有看到检查响应cookie是否存在并获取其属性的方法.但是还有一些方法可以做到吗?
在一个动作方法中,我尝试在响应对象上设置两个cookie,然后立即尝试访问它们.但intellisense没有显示允许我访问它们的任何方法,属性或索引器:
有一会儿,我想也许我可以使用Response.Cookies.ToString();并解析信息来查找我的cookie信息,但是,唉,该ToString()调用返回"Microsoft.AspNet.Http.Internal.ResponseCookies",因为该对象不会覆盖默认实现.
只是为了好玩,我还检查了GitHub的当前dev分支,看看自RC1以来接口是否已经改变,但它没有.因此,给定此接口,如何检查响应cookie的存在并获取其属性?我曾经考虑过通过响应头集合进行攻击,但这看起来很蹩脚.
Sim*_*n B 12
Microsoft.AspNetCore.Http.Extensions调用中有一个可用的扩展方法GetTypedHeaders()。可以调用它HttpContext.Response来读取Set-Cookie标题。例如,在中间件中,我们可能想要拦截Set-Cookie响应标头并替换它:
public async Task Invoke(HttpContext httpContext)
{
httpContext.Response.OnStarting(state =>
{
var context = (HttpContext)state;
var setCookieHeaders = context.Response.GetTypedHeaders().SetCookie;
// We assume only one cookie is found. You could loop over multiple matches instead.
// setCookieHeaders may be null if response doesn't contain set-cookie headers
var cookie = setCookieHeaders?.FirstOrDefault(x => x.Name == "mycookiename");
if (cookie == null)
{
return Task.CompletedTask;
}
var opts = new CookieOptions
{
HttpOnly = true,
Expires = DateTimeOffset.Now.AddHours(12),
SameSite = SameSiteMode.Lax,
Secure = true
};
context.Response.Cookies.Delete(cookie.Name.Value);
context.Response.Cookies.Append(cookie.Name.Value, "mynewcookievalue", opts);
return Task.CompletedTask;
}, httpContext);
await _next(httpContext);
}
Run Code Online (Sandbox Code Playgroud)
这是我如何value从响应中获取cookie.如果需要,可以使用这样的东西来获取整个cookie:
string GetCookieValueFromResponse(HttpResponse response, string cookieName)
{
foreach (var headers in response.Headers.Values)
foreach (var header in headers)
if (header.StartsWith($"{cookieName}="))
{
var p1 = header.IndexOf('=');
var p2 = header.IndexOf(';');
return header.Substring(p1 + 1, p2 - p1 - 1);
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
肖恩的回答有一个明显的问题:它将匹配任何具有匹配值的 HTTP 标头。这个想法应该是只匹配cookies。
像这样的小改动应该可以解决问题:
string GetCookieValueFromResponse(HttpResponse response, string cookieName)
{
foreach (var headers in response.Headers)
{
if (headers.Key != "Set-Cookie")
continue;
string header = headers.Value;
if (header.StartsWith($"{cookieName}="))
{
var p1 = header.IndexOf('=');
var p2 = header.IndexOf(';');
return header.Substring(p1 + 1, p2 - p1 - 1);
}
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
现在检查 cookie 名称将仅针对实际的 cookie 标头。
小智 6
您可以使用此函数获取有关 cookie 设置值的完整信息
private SetCookieHeaderValue GetCookieValueFromResponse(HttpResponse response, string cookieName)
{
var cookieSetHeader = response.GetTypedHeaders().SetCookie;
if (cookieSetHeader != null)
{
var setCookie = cookieSetHeader.FirstOrDefault(x => x.Name == cookieName);
return setCookie;
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6022 次 |
| 最近记录: |