简体   繁体   中英

Stop url encoding cookie

Consider the following ASP.net web api controller method. For demo purpose it returns a cookie. the session-id cookie has a base64 encoded data. When I add the cookie to the response with response.Headers.AddCookies(new CookieHeaderValue[] { cookie }); it url encodes the data (Documentation is here ). Is there any way I can attach the cookie without encoding it?

  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;
  }

I have the same problem because i want to create LTPA Token cookie used by Lotus Domino SSO web applications and this cookie is base64 encoded and use special characters in cookie like "+=....". I find three way to solve this problem:

  1. OWIN extension in Startup.cs

app.Use((context, next) => { context.Response.Headers....; //here decode and replace the cookies return next.Invoke(); });

  1. using javascript after page load with cookies:

    document.cookie = encodeURIComponent(document.cookie);

  2. or the best way is to create extension like this:

     /// <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")); } }

And you can use it like this:

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

or

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

And this solve the problem.

In a NET Core project , I did an extension method to HttpResponse. In my case, I needed to replace all space characters in order to have a valid cookie value. keep in mind what kind of values you need to save and then update the string properly before creating the 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());
    }
}

Use it like this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM