I'm having a problem passing cookies in ASP.NET to a new URL. I add cookies to the Response like so:
Response.Cookies.Add(new HttpCookie("Username", Username.Text));
I then issue a redirect:
Response.Redirect(returnURL);
On the new page that I am redirected to, the cookie collection is empty. I try to retrieve a cookie like so:
Request.Cookies["Username"].Value;
Can anyone think of why the cookies are not being passed?
EDIT:
Further info I forgot to add - on the second attempt within the same browser session, the cookies ARE passed correctly with the redirect.
EDIT #2: I have found that if I use "localhost" instead of the actual domain name in the redirect URL, then the cookies are passed correctly on first login. So its only when the redirect URL is the actual domain name that it doesn't work. Strange.
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
if (Request.QueryString["AcceptsCookies"] == null)
{
Response.Cookies["TestCookie"].Value = "ok";
Response.Cookies["TestCookie"].Expires =
DateTime.Now.AddMinutes(1);
Response.Redirect("TestForCookies.aspx?redirect=" +
Server.UrlEncode(Request.Url.ToString()));
}
else
{
Label1.Text = "Accept cookies = " +
Server.UrlEncode(
Request.QueryString["AcceptsCookies"]);
}
}
}
This link will help you understand reading and writing cookies in C#.
Also, this page would be useful in case you are familiar with VB more than C#.
Browsers only send cookies back to pages in the same domain as the page that set the cookie.
So if you go to page http://localhost/login.aspx
and the server then proceeds to set a cookie and redirect to (for instance) http://mymachinename/default.aspx
, the cookie will not be sent from the browser to the server when requesting the second url because its not in the same domain.
To get the cookie back you would either have to redirect to http://localhost/default.aspx
or you would have to start by originally going to http://mymachinename/login.aspx
.
According to HTTP State Management Mechanism
Origin servers MAY send a Set-Cookie response header with any
response. User agents MAY ignore Set-Cookie headers contained in
responses with 100-level status codes but MUST process Set-Cookie
headers contained in other responses (including responses with 400-
and 500-level status codes). An origin server can include multiple
Set-Cookie header fields in a single response. The presence of a
Cookie or a Set-Cookie header field does not preclude HTTP caches
from storing and reusing a response.
So REDIRECTs (3xx) are in the 'other' responses so they should be processed by the browser, which may then drop them for all kinds of reasons. One such cause of the browser rejecting the cookie is when the domain attribute of the cookie is specified and does not have enough dots (like 'localhost') or when the path attribute of the cookie does not case-match the actual path in the URL (cookie's path is case sensitive).
I've been facing the same issue in a .NET Core 2.1 WebApp . After searching a while I found out that I could use the following to force a cookie not to be lost upon a redirect response.
HttpContext.Response.Cookies.Append("cookie-name", "cookie-value", new CookieOptions { IsEssential = true });
The docs mention that this property "indicates if this cookie is essential for the application to function correctly. If true then consent policy checks may be bypassed. The default value is false."
This might be an option for you!
Typically I make my server produce a Base64 string that I retrieve via ajax. When the ready object is available, I then make the 'attachment' from the base 64 string on the client. That way, I can respond consistently across browsers to a download complete.