39

I'm surprised I couldn't find any answers.

How do I set my sessionid in my cookie to expire at the end of session? (when the browser closes or the user has been inactive for a period of time).

The two solutions I found were

(httpcookie).Expires = HttpContext.Current.Session.Timeout

Which gave me a compile error so I don't know if the user checked his code before posting. And the other was to set the expire date to 1 day ago which my gut says is wrong. How do I do this?

Taran
  • 12,822
  • 3
  • 43
  • 47

4 Answers4

53

You're talking about a non-persistent cookie. By default asp.net sends cookies in that way. The main difference between them are that a persistent cookie has an expires value set.

So, if you don't want the cookie to persist, then do not set the expires value.

That said, the cookie will remain in memory until the browser is actually closed. Let's say they browse to your site and you set a non-persistent cookie. They do things and browse away. Later they, using the same browser instance, come back to your site. The cookie will still be there.

Now, if they closed the browser at any point, then the cookie would be flushed out.

Point is, don't set the expires header. Especially not to when the session date expires. Session dates are generally only 20 or so minutes in the future, but the expiration date rolls forward as the user browses through your site.

===== update =====

I used the following code for testing:

    protected void Page_Load(object sender, EventArgs e) {
        if (!Page.IsPostBack) {
            HttpCookie c = Request.Cookies["test"];
            if (c != null) {
                Response.Write(String.Format("test value is {0} <br />", c.Value));
            }
        } else {
            HttpCookie c = new HttpCookie("test");
            c.Value = "HERE IT IS";
            Response.Cookies.Add(c);
        }
    }

    protected void Button1_Click(object sender, EventArgs e) {
        Response.Write("clicked<br />");
    }

the .aspx file simple had a button which fired that button1_click handler. When I initially browse to it using any of the latest browsers (ie, firefox, chrome) there is no cookie. After I click the button a cookie is set. Then I closed the browser completely, reopened and browsed back to the site. In all cases the cookie was gone.

NotMe
  • 87,343
  • 27
  • 171
  • 245
  • 2
    cool, so the solution is dont touch anything, just set the cookie value and leave it at that. I thought there was more to it. –  Sep 17 '10 at 17:07
  • Before i mark this as accepted i want to know. I closed my firefox (3.6.10) browser and reopened it. I was still logged in. Why? It looks like updating/setting the expiry to 30mins ahead seems like a good solution. –  Sep 17 '10 at 21:47
  • 2
    You might first want to delete ALL of your cookies related to your test site. Then try it. Also, make sure you close all instances of firefox that may be open. The cookie might have still been there from when you were testing the expiration date. – NotMe Sep 17 '10 at 21:57
  • I just tested it with Firefox 3.6.10 and it cleared out as expected. – NotMe Sep 17 '10 at 22:03
  • Weird. I know i did it right so i tested it again. It turns out first time around i had multiple tabs open and used the save and quit feature. I didnt know that prevents cookies from expiring. Well done. -edit- I tested on opera and it expires the cookies even when i close with multiple tabs. I'm happy with these results. –  Sep 18 '10 at 01:34
  • If user log in to the asp.net website and leave it ideal for 30 minutes, Session will be destroyed, but cookie will still exists as that window is not closed. Can you pls suggest any workaround for that ?? Also what if user has clicked on remember me ? - I think at that time we need to set cookie expiry to some long value and clear the cookie on log out. – Jay Shah Jun 01 '18 at 15:26
11

It's important to note that these days you can't count on a session cookie being deleted when the user closes the browser. Both Chrome and Firefox made that change back in 2012 or so - see the various links at this answer.

Now, failing to delete session cookies strikes me as a terrible, horrible, no good, very bad security hole, not to mention a violation of every relevant RFC, but apparently our Google (and Mozilla) Overlords know better.

I'm not sure what the best workaround is, but the approach I'm taking is to reset the "Expires" property on the cookie to an hour in the future after each call. That's not precisely the desired behavior, but I think it's better than allowing crucial cookies to stick around basically forever.

Open to other suggestions or clarifications.

Community
  • 1
  • 1
Ken Smith
  • 20,305
  • 15
  • 100
  • 147
  • If you spend quality time constructing the Cookie, it can be a life saver in Request-based Load Balancing. Of course, nothing is 100% secure but an Encrypted Ticket package inside of the Cookie is the best approach without using other Obfuscation patterns. – GoldBishop Dec 01 '17 at 02:43
2

TimeOut returns an int, Expires expects DateTime, which is why that code will not compile. Setting the expiration date to date in the past immediately revokes the cookie, so that's probably not what you want. If you left the expiration date unused, the cookie would expire as soon as the user closed the browser.

If you want the cookie tied to the particular Session, why involve the cookie in the first place? You could certainly keep extending the cookie's expiration date each time the user extended the session by using your application, but that seems like unnecessary work. Just use Session.

Feel free to elaborate on the problem.

Anthony Pegram
  • 123,721
  • 27
  • 225
  • 246
  • That meant skip persisting things to a cookie and just use the session. If you actually need to know how to *use* the session, there are questions for that. A short example is `Session["someKey"] = someString; string retrievedValue = (string)Session["someKey"];` – Anthony Pegram Sep 17 '10 at 17:22
  • +1. I want to mention that `HttpContext.Current.Session` was null so i just went with cookies instead and extend the expiration date each time the user visits as you mentioned. –  Sep 17 '10 at 21:49
  • 1
    In some scenarios, web-farm in particular, the SessionState is not guaranteed with a Request-based Load balancer. Without using a State Management implementation, a Cookie is the only best approach available. In my cases, I incorporate an Encrypted Ticket inside the Cookie and apply the Encrypted at rest approach. – GoldBishop Dec 01 '17 at 02:41
1

Do NOT use Login control, it makes it harder.

protected void btnLogin_Click(object sender, EventArgs e) 
{
    // Check user and password in database
    bool isValidUser = ValidateUser(txtUsername.Text, txtPassword.Text);

    // Set cookie to be not persistent - this means if the user closes the browser, 
    //autentification cookie will be deleted and the user is not longer logged 
    bool isPersistentCookie = false;

    // Login user with the new username
    FormsAuthentication.SetAuthCookie(txtUsername.Text, isPersistentCookie);
}