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.
Why does the property SessionID on the Session-object in an ASP.NET-page change between requests?
I have a page like this:
...
<div>
SessionID: <%= SessionID %>
</div>
...
And the output keeps changing every time I hit F5, independent of browser.
This is the reason
When using cookie-based session state, ASP.NET does not allocate storage for session data until the Session object is used. As a result, a new session ID is generated for each page request until the session object is accessed. If your application requires a static session ID for the entire session, you can either implement the Session_Start method in the application's Global.asax file and store data in the Session object to fix the session ID, or you can use code in another part of your application to explicitly store data in the Session object.
http://msdn.microsoft.com/en-us/library/system.web.sessionstate.httpsessionstate.sessionid.aspx
So basically, unless you access your session object on the backend, a new sessionId will be generated with each request
EDIT
This code must be added on the file Global.asax. It adds an entry to the Session object so you fix the session until it expires.
protected void Session_Start(Object sender, EventArgs e)
{
Session["init"] = 0;
}
There is another, more insidious reason, why this may occur even when the Session object has been initialized as demonstrated by Cladudio.
In the Web.config, if there is an <httpCookies> entry that is set to requireSSL="true" but you are not actually using HTTPS: for a specific request, then the session cookie is not sent (or maybe not returned, I'm not sure which) which means that you end up with a brand new session for each request.
I found this one the hard way, spending several hours going back and forth between several commits in my source control, until I found what specific change had broken my application.
In my case I figured out that the session cookie had a domain that included www. prefix, while I was requesting page with no www..
Adding www. to the URL immediately fixed the problem. Later I changed cookie's domain to be set to .mysite.com instead of www.mysite.com.
my problem was that we had this set in web.config
<httpCookies httpOnlyCookies="true" requireSSL="true" />
this means that when debugging in non-SSL (the default), the auth cookie would not get sent back to the server. this would mean that the server would send a new auth cookie (with a new session) for every request back to the client.
the fix is to either set requiressl to false in web.config and true in web.release.config or turn on SSL while debugging:
Using Neville's answer (deleting requireSSL = true, in web.config) and slightly modifying Joel Etherton's code, here is the code that should handle a site that runs in both SSL mode and non SSL mode, depending on the user and the page (I am jumping back into code and haven't tested it on SSL yet, but expect it should work - will be too busy later to get back to this, so here it is:
if (HttpContext.Current.Response.Cookies.Count > 0)
{
foreach (string s in HttpContext.Current.Response.Cookies.AllKeys)
{
if (s == FormsAuthentication.FormsCookieName || s.ToLower() == "asp.net_sessionid")
{
HttpContext.Current.Response.Cookies[s].Secure = HttpContext.Current.Request.IsSecureConnection;
}
}
}
Another possibility that causes the SessionID to change between requests, even when Session_OnStart is defined and/or a Session has been initialized, is that the URL hostname contains an invalid character (such as an underscore). I believe this is IE specific (not verified), but if your URL is, say, http://server_name/app, then IE will block all cookies and your session information will not be accessible between requests.
In fact, each request will spin up a separate session on the server, so if your page contains multiple images, script tags, etc., then each of those GET requests will result in a different session on the server.
Further information: http://support.microsoft.com/kb/316112
My issue was with a Microsoft MediaRoom IPTV application. It turns out that MPF MRML applications don't support cookies; changing to use cookieless sessions in the web.config solved my issue
<sessionState cookieless="true" />
Here's a REALLY old article about it:
Cookieless ASP.NET
in my case it was because I was modifying session after redirecting from a gateway in an external application, so because I was using IP instead on localhost in that page url it was actually considered different website with different sessions.
In summary
pay more attention if you are debugging a hosted application on IIS instead of IIS express and mixing your machine http://Ip and http://localhost in various pages
In my case this was happening a lot in my development and test environments. After trying all of the above solutions without any success I found that I was able to fix this problem by deleting all session cookies. The web developer extension makes this very easy to do. I mostly use Firefox for testing and development, but this also happened while testing in Chrome. The fix also worked in Chrome.
I haven't had to do this yet in the production environment and have not received any reports of people not being able to log in. This also only seemed to happen after making the session cookies to be secure. It never happened in the past when they were not secure.
Update: this only started happening after we changed the session cookie to make it secure. I've determined that the exact issue was caused by there being two or more session cookies in the browser with the same path and domain. The one that was always the problem was the one that had an empty or null value. After deleting that particular cookie the issue was resolved. I've also added code in Global.asax.cs Sessin_Start method to check for this empty cookie and if so set it's expiration date to something in the past.
HttpCookieCollection cookies = Response.Cookies;
for (int i = 0; i < cookies.Count; i++)
{
HttpCookie cookie = cookies.Get(i);
if (cookie != null)
{
if ((cookie.Name == "ASP.NET_SessionId" || cookie.Name == "ASP.NET_SessionID") && String.IsNullOrEmpty(cookie.Value))
{
//Try resetting the expiration date of the session cookie to something in the past and/or deleting it.
//Reset the expiration time of the cookie to one hour, one minute and one second in the past
if (Response.Cookies[cookie.Name] != null)
Response.Cookies[cookie.Name].Expires = DateTime.Today.Subtract(new TimeSpan(1, 1, 1));
}
}
}
This was changing for me beginning with .NET 4.7.2 and it was due to the SameSite property on the session cookie. See here for more info: https://devblogs.microsoft.com/aspnet/upcoming-samesite-cookie-changes-in-asp-net-and-asp-net-core/
The default value changed to "Lax" and started breaking things. I changed it to "None" and things worked as expected.
Be sure that you do not have a session timeout that is very short, and also make sure that if you are using cookie based sessions that you are accepting the session.
The FireFox webDeveloperToolbar is helpful at times like this as you can see the cookies set for your application.
Session ID resetting may have many causes. However any mentioned above doesn't relate to my problem. So I'll describe it for future reference.
In my case a new session created on each request resulted in infinite redirect loop. The redirect action takes place in OnActionExecuting event.
Also I've been clearing all http headers (also in OnActionExecuting event using Response.ClearHeaders method) in order to prevent caching sites on client side. But that method clears all headers including informations about user's session, and consequently all data in Temp storage (which I was using later in program). So even setting new session in Session_Start event didn't help.
To resolve my problem I ensured not to remove the headers when a redirection occurs.
Hope it helps someone.
I ran into this issue a different way. The controllers that had this attribute [SessionState(SessionStateBehavior.ReadOnly)] were reading from a different session even though I had set a value in the original session upon app startup. I was adding the session value via the _layout.cshtml (maybe not the best idea?)
It was clearly the ReadOnly causing the issue because when I removed the attribute, the original session (and SessionId) would stay in tact. Using Claudio's/Microsoft's solution fixed it.
I'm on .NET Core 2.1 and I'm well aware that the question isn't about Core. Yet the internet is lacking and Google brought me here so hoping to save someone a few hours.
Startup.cs
services.AddCors(o => o.AddPolicy("AllowAll", builder =>
{
builder
.WithOrigins("http://localhost:3000") // important
.AllowCredentials() // important
.AllowAnyMethod()
.AllowAnyHeader(); // obviously just for testing
}));
client.js
const resp = await fetch("https://localhost:5001/api/user", {
method: 'POST',
credentials: 'include', // important
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
Controllers/LoginController.cs
namespace WebServer.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class UserController : ControllerBase
{
[HttpPost]
public IEnumerable<string> Post([FromBody]LoginForm lf)
{
string prevUsername = HttpContext.Session.GetString("username");
Console.WriteLine("Previous username: " + prevUsername);
HttpContext.Session.SetString("username", lf.username);
return new string[] { lf.username, lf.password };
}
}
}
Notice that the session writing and reading works, yet no cookies seem to be passed to the browser. At least I couldn't find a "Set-Cookie" header anywhere.
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 have two sites set up on one Windows 2008 IIS server. On the first site, the user hits the web page and the following simple C# code is used to create a cookie.
<%
HttpCookie myCookie = new HttpCookie("MyTestCookie");
myCookie.Value = "Hi";
myCookie.Expires = DateTime.Now.AddMinutes(1);
Response.Cookies.Add(myCookie);
>%
I've verified that this site can in fact "see" the cookie and I can use the following code to display its value:
<% Response.Write(Request.Cookies["MyTestCookie"].Value); %>
On the other site hosted on the exact same server. I use the following code to see if the cookie is assigned a value:
if (Request.Cookies["MyTestCookie"] == null)
{
lblErr.Text = "Cookie is null.";
}
else
{
lblErr.Text = Request.Cookies["MyTestCookie"].Value;
}
It's null. Just a few days before, however, it wasn't null. In the full code of the actual site, it was working for all but a few users. In trying to troubleshoot these particular users, it stopped working for everyone.
I don't know what I'm doing wrong, but I need to pass values between two sites which are completely independent and unaware of each other. I thought first-party cookies work fine if on the same server. What am I doing wrong?
Cookies are associated with the URL they come from - the browser would not send to site B the cookies received from site A (and vice-versa).
EDIT
If the problem is user-dependant maybe it is related to the cookie settings in the browser - if some user are blocking cookies for example.
Try setting the Path property to "/" and make sure the sites share the same domain name.
If they are on different sub domains, set the Domain property to domainname.com (your domain name).
Edit:
Your code should look like this:
if (Request.Cookies["MyTestCookie"] == null)
{
HttpCookie myCookie = new HttpCookie("MyTestCookie");
myCookie.Path = "/";
myCookie.Domain = "domain.com";
myCookie.Value = "Hi";
myCookie.Expires = DateTime.Now.AddMinutes(1);
Response.Cookies.Add(myCookie);
lblErr.Text = "Cookie was null.";
}
else
{
lblErr.Text = Request.Cookies["MyTestCookie"].Value;
}
The expiry time you set for the cookie (one minute from now) is a bit too short. Try setting it to 6 months in the future and see if that helps.
Client has a site at a.url.com. Client creates a cookie with host as ".url.com" and path as "/". Client redirects to us at b.url.com. Client has a coding issue that requires us to delete the cookie (long story).
The following code is not adjusting the expiration at all in our test or production environments but is working fine locally.
if (Request.Cookies["cookie"] != null)
{
HttpCookie myCookie = new HttpCookie("cookie");
myCookie.Expires = DateTime.Now.AddDays(-1d);
Response.Cookies.Add(myCookie);
}
Any ideas?
We've figured it out. We needed to add one line of code to manually set the domain. Makes total sense now.
if (Request.Cookies["cookie"] != null)
{
HttpCookie myCookie = new HttpCookie("cookie");
myCookie.Domain = ".url.com";
myCookie.Expires = DateTime.Now.AddDays(-1d);
Response.Cookies.Add(myCookie);
}
is this a third party cookie? If so, the default security settings in IE will prevent cookie writing in the "internet" zone but it is allowed in your local zone.
Here's a hack. I am just posting this in case you find out that you cannot do what you want due to some security issue preventing you handling the issue on the second site.
You could send a request to the first site to clear the cookie via redirect and have that site bounce the user back again. Like I said, this is very hackish (or I suppose marketing would call it inter-site cooperative security feature).
Hopefully, there's a better approach, but at least you have an alternative if no other ones are forthcoming.
If you cannot get it working in C# you might want to consider seeing if you can manipulate the cookies in javascript.
Gary