Obaid
Obaid

Reputation: 1445

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

Upvotes: 3

Views: 6550

Answers (3)

TotPeRo
TotPeRo

Reputation: 6781

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've found 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();
    });
    
  2. Using JavaScript after page load with cookies:

    document.cookie = encodeURIComponent(document.cookie);
    
  3. 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.

Upvotes: 4

Daniel
Daniel

Reputation: 2998

Use headers to set your cookie value:

context.Response.Headers.AppendValues("Set-Cookie", "Key=Value; path=/");

Replace Key with your Cookie Key and Value with desired value

Upvotes: 0

AMore
AMore

Reputation: 179

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

Upvotes: 6

Related Questions