Reputation: 1445
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
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:
OWIN extension in Startup.cs
app.Use((context, next) =>
{
context.Response.Headers....;
//here decode and replace the cookies
return next.Invoke();
});
Using JavaScript after page load with cookies:
document.cookie = encodeURIComponent(document.cookie);
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
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
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