停止url编码cookie

时间:2014-05-02 12:32:52

标签: c# asp.net-mvc asp.net-web-api

考虑以下ASP.net web api控制器方法。出于演示目的,它返回一个cookie。 session-id cookie具有base64编码数据。当我将cookie添加到带有response.Headers.AddCookies(new CookieHeaderValue[] { cookie });的响应时,它会对数据进行编码(文档为here)。有没有办法在没有编码的情况下附加cookie?

  public HttpResponseMessage LogMeIn()
  {
     var response = Request.CreateResponse<Models.UserAuthResponse>(new Models.UserAuthResponse());

     var cookie = new CookieHeaderValue("session-id", "K2QRkQaSnwCBpRrAgI1K3w9kTgbArc+xdIJI64e2hz0=");
     cookie.Expires = DateTimeOffset.Now.AddDays(1);
     cookie.Domain = ".example.com";
     cookie.Path = "/";
     response.Headers.AddCookies(new CookieHeaderValue[] { cookie });
     return response;
  }

2 个答案:

答案 0 :(得分:2)

我遇到了同样的问题,因为我想创建Lotus Domino SSO Web应用程序使用的LTPA令牌cookie,这个cookie是base64编码的,并在cookie中使用特殊字符,如“+ = ....”。 我找到了解决这个问题的三种方法:

  1. Startup.cs中的OWIN扩展
  2. app.Use((context, next) => { context.Response.Headers....; //here decode and replace the cookies return next.Invoke(); });

    1. 在使用Cookie加载页面后使用javascript:

      document.cookie = encodeURIComponent(document.cookie);

    2. 或最好的方法是创建这样的扩展名:

      /// <summary>
      ///
      /// </summary>
      public static class CookieExtensions
      {
          /// <summary>
          /// Add a new cookie and value
          ///
          /// </summary>
          /// <param name="header"></param>
          /// <param name="key"/><param name="value"/>
          public static void AppendUrlDecodedCookie(this IHeaderDictionary header, string key, string value)
          {
              header.AppendValues("Set-Cookie", key + "=" + value + "; path=/");
          }
      
          ///  <summary>
          ///  Add a new cookie
          ///
          ///  </summary>
          /// <param name="header"></param>
          /// <param name="key"/><param name="value"/><param name="options"/>
          public static void AppendUrlDecodedCookie(this IHeaderDictionary header, string key, string value, CookieOptions options)
          {
              if (options == null)
                  throw new ArgumentNullException("options");
              bool flag1 = !string.IsNullOrEmpty(options.Domain);
              bool flag2 = !string.IsNullOrEmpty(options.Path);
              bool hasValue = options.Expires.HasValue;
              header.AppendValues("Set-Cookie",
                  key + "=" + (value ?? string.Empty) + (!flag1 ? (string) null : "; domain=") +
                  (!flag1 ? (string) null : options.Domain) + (!flag2 ? (string) null : "; path=") +
                  (!flag2 ? (string) null : options.Path) + (!hasValue ? (string) null : "; expires=") +
                  (!hasValue
                      ? (string) null
                      : options.Expires.Value.ToString("ddd, dd-MMM-yyyy HH:mm:ss ",
                          (IFormatProvider) CultureInfo.InvariantCulture) + "GMT") +
                  (!options.Secure ? (string) null : "; secure") + (!options.HttpOnly ? (string) null : "; HttpOnly"));
          }
      }
      
    3. 你可以像这样使用它:

      response.Headers.AppendUrlDecodedCookie("key", "val");
      

      response.Headers.AppendUrlDecodedCookie("key", "val", new Microsoft.Owin.CookieOptions
                                      {
                                          Path = "/",
                                          Domain = ="domain.com",
                                          Expires = Date...
                                      });
      

      这解决了这个问题。

答案 1 :(得分:0)

在NET Core项目中,我对HttpResponse做了扩展。就我而言,我需要替换所有空格字符以具有有效的cookie值。在创建setCookieHeaderValue之前,请记住要保存哪种类型的值,然后正确更新字符串。

    public static class CookiesExtensions
{
    public static void AppendUnencodedCookie(this HttpResponse response, string key, string value, CookieOptions options)
    {
        if (options == null)
        {
            throw new ArgumentNullException(nameof(options));
        }

        response.Cookies.Delete(key);

        var setCookieHeaderValue = new SetCookieHeaderValue(key, value.Replace(" ","+"))
        {
            Domain = options.Domain,
            Path = options.Path,
            Expires = options.Expires,
            MaxAge = options.MaxAge,
            Secure = options.Secure,
            SameSite = (Microsoft.Net.Http.Headers.SameSiteMode)options.SameSite,
            HttpOnly = options.HttpOnly
        };

        response.Headers[HeaderNames.SetCookie] = StringValues.Concat(response.Headers[HeaderNames.SetCookie], setCookieHeaderValue.ToString());
    }
}

像这样使用它:

Context.Response.AppendUnencodedCookie(cookieName, cookieValue, options);