16

My research indicates that, if I create a cookie and don't set the expiration date, it will expire when the browser is closed.

So I created a cookie like this:

Response.Cookies.Set(new HttpCookie("MyKey", "X"));

But when I close the browser and then reopen it, the following expression equals true:

Request.Cookies["MyKey"] != null

How can I have the cookie expire when the browser session ends?

Note: For my purposes, using static data instead of a cookie seems ideal. But my understanding is that an ASP.NET can restart for a variety of reasons, and that could pull the rug out from under the current user if I lost this setting.

Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466
  • 1
    Do you want to have the cookie on the server expire after the browser session ends? How do you check the value of `Request.Cookies["MyKey"]` after the browser is closed? – Stobor Jul 19 '13 at 01:34
  • I want the cookie on the client, not the server. I check the value of the cookie after the browser closes when the browser is reopened and the page is reloaded. – Jonathan Wood Jul 19 '13 at 01:35
  • Just curious if there's some undocumented default value in play - place a breakpoint on or after `Response.Cookies.Add` and inspect the current cookie set values to make sure the expiration is set (or not set) as expected. Also, inspect the actual cookie in your browser to make sure the expiration is set (or not set) as expected there as well. – bob-the-destroyer Jul 19 '13 at 02:36
  • I changed `Response.Cookies.Add()` to `Response.Cookies.Set()`. After that line, the cookies appear correct. Visual Studio reports the expiration date as 01/01/0001 00:00:00 and my browser (Chrome) displays the expiration as "When the browsing session ends". Yet when I do nothing but close the browser and reload it (which automatically loads the pages that were up before), the cookie is still there. – Jonathan Wood Jul 19 '13 at 03:33
  • Watch your traffic and verify that the cookie is being sent from the client. You likely are reloading a cached page. – EricLaw Jul 19 '13 at 03:58
  • Good thought, but I have a breakpoint in the code that constructs the page. It appears to be getting hit. – Jonathan Wood Jul 19 '13 at 03:59
  • 3
    "which automatically loads the pages that were up before" - I suspect your browser has some form of "reload where I was before" setting enabled. With that on, the browser session does not end when you exit the browser; and so exiting the browser does not trigger the deletion of the cookie. – Stobor Jul 19 '13 at 05:08
  • 1
    Yep, here's the relevant settings in Chrome: https://support.google.com/chrome/answer/95421 – Stobor Jul 19 '13 at 05:10
  • You got me. I tried removing that tab and reloading the site in a new tab. I also tried removing the tab before closing the browser, then reloading the site in a new tab after restarting the browser. In all cases, the cookie still exists. Guess I'll try testing with some other browsers tomorrow. – Jonathan Wood Jul 19 '13 at 05:12
  • Yep, as far as I know, none of those actions end a browser session when you have session persistence turned on... The only option I know of is to [turn off one of the relevant settings in Chrome](https://support.google.com/chrome/answer/95421). – Stobor Jul 19 '13 at 05:49
  • Thanks, I'm checking that out. However, I don't see any way to turn that option off for every visitor of my website so I'm not seeing any good options here. – Jonathan Wood Jul 19 '13 at 14:34
  • 1
    Possible duplicate of http://stackoverflow.com/questions/3737285/set-cookie-to-expire-at-end-of-session-asp-net – goodeye Sep 22 '14 at 15:53
  • @goodeye: I don't see the point in suggesting this question is a possible duplicate months after this question got a lot of comments and a couple of answers. Moreover, the question you referenced is different. That question is about how to set a cookie to expire, my question here was about why it doesn't always work. – Jonathan Wood Sep 22 '14 at 16:04
  • I was going by "how to I get it to expire", which is what the other question asks, and discusses the same problems. Duplicate questions with answers can be merged if truly duplicate, hence my suggestion. – goodeye Sep 22 '14 at 16:45
  • "I also tried removing the tab before closing the browser" - stating the obvious here but just to clarify and hopefully assist others, it's not enough to only close the one tab before closing the browser, you also have to close _all_ other tabs pointing to the same domain or the session cookie will not be removed if your browser is configured to restore tabs on start-up. – WynandB Dec 15 '14 at 04:22

3 Answers3

18

It appears the issue is as Stober described. You can set a cookie to expire at the end of the browser session by setting the HttpCookie.Expires property to DateTime.MinDate, or not setting the property at all.

However, at least with Chrome's pick up where you left off settings, it appears that the browser session does not necessarily end when the browser closes. When closed and then reopened, the Chrome browser picks up right where it left off, as if the session never ended. This includes continuing to use cookies set expire at the end of the session.

I tried my same code on FireFox. Closing and reopening the browser caused the cookie to expire, exactly as expected.

So while there are some general rules, in the end this behavior is totally up to the browser.

Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466
1

You can catch this on the next Session_start event. If you already have an authenticated user immediately when a brand new session starts, then you must have gotten that info from a stale cookie. Just null out the user info and let Login redirects take care of the rest.

Something like this in global.asax.cs:

protected void Session_start()
{
    // starting a session and already authenticated means we have an old cookie
    var existingUser = System.Web.HttpContext.Current.User;
    if (existingUser != null && existingUser.Identity.Name != "")
    {
        // clear any existing cookies
        IAuthenticationManager authMgr = System.Web.HttpContext.Current.GetOwinContext().Authentication;
        authMgr.SignOut("MyCookieType")

        // manually clear user from HttpContext so Authorize attr works
        System.Web.HttpContext.Current.User = new ClaimsPrincipal(new ClaimsIdentity());
    }

}
  • Code may vary somewhat depending on how you're authenticating users

See also:

KyleMit
  • 30,350
  • 66
  • 462
  • 664
0

Just set the Expires property of your HttpCookie instance to DateTime.MinDate and it will expire after the browser session ends.

However, this is actually not a safe way of protecting something with cookies, because the cookies are in fact valid for ever. It depends on the client implementation if the cookies are thrown away or not. If some bad person intercepts your cookies they will have access for ever.

See also: MSDN - Cookie.Expires Property

KyleMit
  • 30,350
  • 66
  • 462
  • 664
Kees
  • 1,408
  • 1
  • 15
  • 27
  • Setting the expiration date to `DataTime.MinDate` has the exact same effect as not setting the expiration date at all. In Chrome (at least with certain settings), it means the cookie doesn't not expire when the browser session ends. (Or at least the "browser session" does not end when the browser is closed.) – Jonathan Wood Jul 21 '13 at 16:46