I'm writing an asp.net application and I am saving the cookies correctly (stored in internet files). When I open the file it contains: access_token mylongalphanumberictoken /domainname (no spaces between them).
The problem is that when I check the client for a cookie, I receive null. Can anyone tell me why this is happening and how do i fix it?
public void createCookie(string tokenVal)
{
authCookie = new HttpCookie("access_token",tokenVal);
authCookie.Expires = DateTime.Now.AddDays(60.00); //Token expires in 60 days
authCookie.Domain = ServerDomain.Authority;
}
check if the client has cookies like this:
if (Request.Cookies["access_token"] != null)
{
currentCookieStore.authCookie = Request.Cookies["access_token"];
}
EDIT: im using: currPage.Response.Cookies.Add(newTokenCookie.OauthCookie) ;
to add the cookies. ServerDomain is the location of my webserver so its machinename.domain
The answer is to add a P3P header to prevent IE from blocking your cookies.
Solution here:
Explanation: Cookie blocked/not saved in IFRAME in Internet Explorer
How to: http://social.msdn.microsoft.com/Forums/windowsazure/en-US/4f74156a-54a0-468b-8496-85913094fc34/issue-while-adding-http-response-header-to-a-site-hosted-in-azure-web-role-running-with-more-than?forum=windowsazuremanagement
Related
My team maintains a suite of C# applications which all share a common set of cookies.
Recently, we had a situation where the cookie size became too large and users began experiencing a 400 error when accessing our production site.
I wrote a little webforms app that would iterate through a list of our cookies and delete them which did not include our shared code that would try to read/write the cookies in Global.asax:
foreach (var c in cookieList)
{
HttpCookie currentUserCookie = HttpContext.Current.Request.Cookies[c];
if (currentUserCookie != null)
{
HttpContext.Current.Response.Cookies.Remove(c);
currentUserCookie.Expires = DateTime.Now.AddDays(-10);
currentUserCookie.Value = null;
HttpContext.Current.Response.SetCookie(currentUserCookie);
}
}
However, all the pages on our site still threw the error. The only solution we could find was to have the users manually delete their cookies.
Is there any we can trigger a deletion of our cookies from the server side and save our users the hassle of manually clearing their cookies? We're using IE11 and Chrome 54.
this line try update existing cookie (it removed from response)
HttpContext.Current.Response.SetCookie(currentUserCookie);
try this..
foreach (var c in cookieList)
{
HttpCookie currentUserCookie = HttpContext.Current.Request.Cookies[c];
if (currentUserCookie != null)
{
HttpContext.Current.Response.Cookies.Remove(c);
currentUserCookie.Expires = DateTime.Now.AddDays(-1);
HttpContext.Current.Response.Cookies.Add(currentUserCookie);
}
}
How to delete cookies in ASP.NET after changing machine key but staying on the same sub-domain?
Currently we have cookies on example.domain.com, but we need to move to wildcard cookies (.domain.com) so that the cookie also work on foo.domain.com. In order to do this, we have manually set a machine key to encrypt/decrypt the asp.net login cookie. Problem is that people that already have the old cookie, will now receive a CryptographicException when trying to access the site (as it tries for some reason to decrypt the old cookie). We have changed the name of the cookie, but it did not help - still receives the error. So we figured out that we wanted to delete all the old cookies. We try do do this on the login site with the following code:
var myCookies = Request.Cookies.AllKeys;
foreach (var cookieName in myCookies)
{
var cookie = Request.Cookies[cookieName];
if (cookie == null) continue;
cookie.Value = "written " + DateTime.Now;
cookie.Expires = DateTime.Now.AddYears(-1);
cookie.Domain = "example.domain.com"
Response.Cookies.Add(cookie);
}
We reach the code, and it runs, but the cookies still remain when inspecting in google chrome resources. So obviously the deletion did not work. We have tried several different ways (adding path ="/", setting cookie.Value to cookie.Value etc. For some strange reason the cookies still remain and we are unavailable to delete them.
So to get back to the original question, how an we delete cookies in ASP.NET MVC 4.5 after changing to a wildcard domain on our cookies and explcitly stating the machine key in the web.config?
If you don't absolutely have to use the same ticket name, your solution should work if you changed the name of the FormsAuthentication cookie:
<forms name=".YOUR_NEW_COOKIE_NAME" /> **
** Note that I've omitted the other attributes from the tag shown, so you wouldn't want to copy/paste it verbatim.
Turns out that by removing cookie.Domain, it managed to delete the cookies. I recon this has to do with the fact that in order to overwrite a cookie, you need to be as specific as possible when adding the replacing cookies. Seeing as the former cookies was added without specifying domain nor path, this is the most specific.
The code that ended up working in this scenario, was therefor:
var myCookies = Request.Cookies.AllKeys;
foreach (var cookieName in myCookies)
{
var cookie = Request.Cookies[cookieName];
if (cookie == null) continue;
cookie.Value = "written " + DateTime.Now;
cookie.Expires = DateTime.Now.AddYears(-1);
Response.Cookies.Add(cookie);
}
I am having trouble with the .Expires cookie attribute. It keeps coming back with 01/01/0001 12:00 AM, when I read the cookie back.
Here is the code. I added in the retrieve just below the save solely for debugging purposes. The save and retrieve happen in different places in the same file. I purposely did not specify a Domain, as I want the cookie to exist site wide.
The data shows up nicely, just not the expiration.
Note: I am testing under Visual Studio 2012 running under local host using .Net Framework 4.
System.Web.UI.Page oPage = this.Page;
HttpCookie oCookie = new HttpCookie("UserData");
// Set the cookie value.
oCookie.Secure = false;
oCookie["Field1"] = strField1;
oCookie["Field2"] = strField2;
oCookie.Expires = DateTime.Now.AddDays(1);
// Add the cookie.
oPage.Response.Cookies.Add(oCookie);
// Get the cookie.
oCookie = new HttpCookie("UserData");
oCookie = oPage.Request.Cookies["UserData"];
The browser will not send anything to the server except the cookie name and value. All of the other properties (expires, domain, path, httponly, ...) cannot be retrieved on requests after the cookie has been set.
The more accepted way to deal with this is to redirect the user to a login page when they try to access a protected resource and display some message along the lines of "You need to log in to view this page. If you were previously logged in, your session may have expired."
(Also note that you should be re-setting the cookie on every request, so that the user will not be logged out if they continue to use the site. It's not clear from your code whether you are doing this or not.)
I was just doing some more Google searching on my problem and saw this link, another posting here on Stackoverflow.
Cookies are always expired
I am also validating using the construct:
if (cookie != null && cookie.Expires > DateTime.Now)...
As several pointed out, expiration checking happens, if you can no longer retrieve the cookie. That is seriously dumb on whomever constructed this architecture. Yes, maybe there should be RequestCookie and ResponseCookie, the difference being ResponseCookie has no Expiry date.
The person who resopnded to me taught me that it is not just expires but other fields too.
In C# code, if using Form Authentication, You can find if cookie is persistent using below code
bool IsCookiePersistent = ((FormsIdentity)User.Identity).Ticket.IsPersistent;
Here Ticket will return the FormsAuthenticationTicket which has Expiration DateTime property.
I'm trying to remove cookies using C# when a user logs out. The code suggestions listed here: remove cookies from browser do not work. I put several of them together in desperation and they are not working.
if (Request.Cookies["loginidcookie"] != null)
{
HttpCookie myCookie = new HttpCookie("loginidcookie");
myCookie.Value = String.Empty;
myCookie.Expires = DateTime.Now.AddDays(-1d);
Response.Cookies.Add(myCookie);
Response.Cookies.Remove("loginidcookie");
}
Response.Redirect("logout.aspx");
So not only am I overwriting the value of the cookie with an empty string, I am setting it to expire yesterday AND removing it from the list of cookies. Yet when I run this code then hit the back button and reload, the cookie is still there with its original value. So how do I get rid of it?
Thank you
Try this instead:
string cookieName = "loginidcookie";
if (Request.Cookies[cookieName ] != null)
{
var myCookie = new HttpCookie(cookieName);
myCookie.Expires = DateTime.Now.AddDays(-1d);
Response.Cookies.Add(myCookie);
}
Response.Redirect("logout.aspx", false);
Note (from here):
You cannot directly delete a cookie on a user's computer. However, you
can direct the user's browser to delete the cookie by setting the
cookie's expiration date to a past date. The next time a user makes a
request to a page within the domain or path that set the cookie, the
browser will determine that the cookie has expired and remove it.
You are adding the Cookie and then Removing it from the collection before the response is sent so you are effectively doing nothing.
HttpCookie myCookie = new HttpCookie("loginidcookie");
... and then below
Response.Cookies.Add(myCookie);
Response.Cookies.Remove("loginidcookie");
If you change the cookie to expire yesterday, you need to leave the cookie in the collection so that the browser takes care of deleting it once it sees the cookie has been updated with an expiration date in the past. In other words, don't call Response.Cookies.Remove("loginidcookie");
Try RedFilter's solution but use Server.Transfer() or Server.TransferRequest() instead of Response.Redirect() which it seems doesn't always let those cookie responses happen due to a possible bug.
Are you checking the cookie after closing the browser? Or reloading the page in the same browser?
If you are opening the page in the same browser you will see the cookie which is expired, but if you opened the new browser and try to access the page again, you would not get the cookie.
I am breaking my head to figure out a browser specific issue (in Firefox and Chrome). I have spent so much time to try fixing this issue that I have finally thought to create a live demo for the experts here to look into this issue. (Hopefully it pays off)
I have two domains www.nkmekal.com and www.incessantcoding.com
Please use Firefox/Chrome to replicate the issue:
Step 1:
Browse http://www.nkmekal.com/createcookie.aspx
The page just creates a cookie. Below is the code that creates the cookie:
// In On_Load of nkmekal.com/createCookie.aspx
HttpCookie cookie = new HttpCookie("DisCookie");
cookie.Value = "djdjd77676ydjdndgdidjkdnhf";
cookie.HttpOnly = true;
cookie.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(cookie);
lblCookieInfo.Text = string.Format("<b>Cookie Name:</b> {0} <br/><br/> <b>Cookie Value:</b> {1} <br/><br/> <b>Cookie Expires On:</b> {2}", cookie.Name, cookie.Value, cookie.Expires);
Step 2:
Now open a new tab in the browser, go to http://www.incessantcoding.com/GoTonkmekal.aspx which basically does a simple 302 redirect to http://www.nkmekal.com/ReadCookie.aspx , below is the code that does this redirect:
// In On_Load of incessantcoding.com/GoTonkmekal.aspx
protected void Page_Load(object sender, EventArgs e)
{
Response.Redirect("http://www.nkmekal.com/ReadCookie.aspx");
}
However I see the below message: (Please see the code of ReadCookie.aspx page in Step 3)
“No Cookie Found :(”
Which means that the domain www.nkmekal.com was unable to read the cookie that it created earlier when you’ve browsed www.nkmekal.com/createcookie.aspx
Step 3:
And the page http://www.nkmekal.com/ReadCookie.aspx just tries to read the above created cookie (in Step 1) and displays cookie data. Below is the code that tries to read the cookie and displays it in the page
// In On_Load of nkmekal/ReadCookie.aspx
HttpCookie cookie = Request.Cookies["DisCookie"];
if (cookie != null)
{
// Resetting expiry date because the browser never sends expiry date to Server,
// as cookies expiration dates are irrelevant to servers.
cookie.Expires = DateTime.Now.AddDays(1);
lblCookieInfo.Text = string.Format("<b>Yes! I found a cookie</b> <br><br><b>Cookie Name:</b> {0} <br/><br/> <b>Cookie Value:</b> {1} <br/><br/> <b>Cookie Expires On:</b> {2}", cookie.Name, cookie.Value, cookie.Expires);
}
else
{
lblCookieInfo.Text = "No Cookie Found :(";
}
The above steps work fine only in IE but not in FireFox/Chrome.
Also, if you want to take a peek at the source code of the two domains you can download them at
http://dl.dropbox.com/u/1248159/incessantcoding.zip
http://dl.dropbox.com/u/1248159/nkmekal.zip
Why am I trying to do this:
So, the reason why I am trying to do this is that there are certain operations that I need to perform in the domain www.incessantcoding.com if there was a cookie created in www.nkmekal.com
And the reason for going with a 302 redirect is that we cannot read cross domain cookies and hence I am trying to get the cookies read from the appropriate domain only (since nkmekal.com can only read its cookies).
Any help/suggestions will be very helpful.
Update:
Also quite interestingly, if steps 1 and 3 are performed (leaving out step 2), the cookie value is read in Firefox and Chrome correctly. Its only the 302 way that isn't working.
When saving up a cookie, the domain of the website is also being saved - this is made to avoid cross-domain data exchange - which means: once you save up a cookie from one host - it CANNOT be read from another whatsoever.
but, you can pass the cookie's data via the URL from your original host:
protected void Page_Load(object sender, EventArgs e)
{
HttpCookie cookie = Request.Cookies["DisCookie"];
if (cookie != null)
{
Response.Redirect("http://www.nkmekal.com/ReadCookie.aspx?data=" + cookie.Value);
}
else Response.Redirect("http://www.nkmekal.com/ReadCookie.aspx");
}
And then just usedata in ReadCookie.aspx.
I have finally figured out an alternative and it works just fine!
Here is what I've did:
If nkmekal.com creates a DisCookie...I am issueing a 302 redirect to incesscantcoding.com with an encrypted token as a querystring value, then incessentcoding.com will create its own DisCookie based on the querystring value for its domain, so if I want to know if a cookie exists for nkmekal.com I will just look at the Cookies collection for a DisCookie in incessantcoding.com ... I tested this scenario and it seems to be working in both firefox and chrome...
AND later I figured that even google does similar thing when a user logs into one of their service websites...
Hope this helps...