如何在Asp.net Core MVC(又名Asp.Net 5 RC1)中检查响应cookie?

Ron*_*n C 10 asp.net-core-mvc

我正在将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是否存在并获取其属性的方法.但是还有一些方法可以做到吗?

在一个动作方法中,我尝试在响应对象上设置两个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)


Tre*_*eaf 8

这是我如何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)


Jar*_*kia 7

肖恩的回答有一个明显的问题:它将匹配任何具有匹配值的 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)