16

I discovered to my astonishment at the first glance that my thinking of how session cookies behave on mobile devices is overruled by reality.

On normal desktop browsers the behavior is to store a session cookie as long as the browser session is active. The session should be closed, if the last browser window/process is closed.

Now on mobile devices you hardly ever close a browser app, you just send it to the background.

I discovered on my Sony Xperia Ray with Android 4 that the session cookie is not expired, even if I purge the browser process. But on a Samsung Tablet device it would. I don't know, how iOS devices behave in that way.

This is a problem!? What should I do to work around it?

For now, I decided to let the cookie expire in one day. But I'm not very happy with that.
Should I lower the lifetime? Perhaps to 8 hours?

yunzen
  • 32,854
  • 11
  • 73
  • 106
  • 1
    What's your goal? End it when the leave the page? Don't make a request in a certain amount of time? Or send their browser to the background? What backend are you using? – Brigand Mar 04 '13 at 13:27
  • I thought of a more general approach. What should I consider etc. In particular my goal is, that I remember the decision, if someone allows to use geo positioning with javascript, but not for ever because of privacy issues (in Germany). Backend usually drupal or typo3 on LAMP. – yunzen Mar 04 '13 at 15:44
  • 1
    How about just letting the user choose a duration, like "allow for 1 hour", "allow for 1 day", "allow forever", etc. – Dave Mar 07 '13 at 01:14
  • well, from design perspective, mobile devices mainly designed for single person use, so i don't think this could be a problem, as many mobile apps keeps their session to keep users "up to date", even works in the background to pull new data and keep track of what you've done to those data. even mail apps that should protect users privacy keeps their sessions and can be easily viewed when someone borrow your mobile device. just an opinion though. – am05mhz Mar 20 '13 at 09:20
  • It's not so much a behavioral problem,but a legal problem (especially in Germany) – yunzen Mar 20 '13 at 11:02

5 Answers5

5

Would it make sense for you to go the HTML5 way and use sessionStorage?

This way you could be independent of the way different devices handle browser sessions, since HTML5 session storage is per-window, thus it is limited to the lifetime of the browser window.

Basically all mobile devices support sessionStorage (see here) and you could have a framework/plugin like jQuery-Session-Plugin (follow this link) handle the session data for you (and provide a fallback to session cookies for old browsers that don't support sessionStorage).

EDIT: In order to show the behavior of sessionStorage vs. localStorage, I've created a fiddle that (for demonstration purpose) uses sessionStorage for storing the width of a div and localStorage for storing the height of the same div:

var randomWidth,
    randomHeight;
if (!(randomWidth= $.session.get("randomWidth"))) {    // assignment
    randomWidth = Math.random() * 300;
    $.session.set("randomWidth", randomWidth, true);
    console.log("just assigned and stored in sessionStorage: randomWidth: " + randomWidth);
} else {
    console.log("from sessionStorage: randomWidth: " + randomWidth);
}
if (!(randomHeight= $.domain.get("randomHeight"))) {    // assignment
    randomHeight = Math.random() * 300;
    $.domain.set("randomHeight", randomHeight, true);
    console.log("just assigned and stored in localStorage: randomHeight: " + randomHeight);
} else {
    console.log("from localStorage: randomHeight: " + randomHeight);
}
$(".test").css({width: randomWidth, height: randomHeight});

Look at the console. You will see that when you initiate a new session of your client browser, the width will variate while the height will stay the same (because local Storage is per domain).

Here is the link to jsfiddle

marty
  • 4,005
  • 22
  • 19
  • 1
    I don't think it will work. I want to have a decision that is made on one page to be read on a different page. – yunzen Mar 14 '13 at 14:54
  • 1
    sessionStorage is global for the domain, if you set an item in sessionStorage on page x, it will be accessible on page y – Rob M. Mar 14 '13 at 15:27
  • @marty - sessionStorage is not per page, it is per domain – Rob M. Mar 14 '13 at 15:30
  • Quoting from https://developer.mozilla.org/en-US/docs/DOM/Storage : > "global object (sessionStorage) that maintains a storage area that's available for the duration of the page session. A page session lasts for as long as the browser is open and survives over page reloads and restores. Opening a page in a new tab or window will cause a *new session* to be initiated." – marty Mar 14 '13 at 15:38
  • @marty Will the sessionStorage behave differently to normal session Cookies on mobile devices? I mean, what does 'as long as the Browser is open' on a smart phone mean? What does it mean on a tablet? – yunzen Mar 18 '13 at 11:47
  • @HerrSerker, I cannot give you a definitive answer because there's such a variety of devices. Best I could do is create a jsfiddle as a means for testing: On an iPad (1st Gen., Safari), for example, I see that the session value remains the same through page refreshes, but gets a new value per tab instance of the page - also when I delete all tabs (but keep Safari open) and then reenter the page, I get a new session value. – marty Mar 18 '13 at 13:05
  • @marty on my xperia ray it bahaves the same way. If I commence the browser app to the background, the sessionStorage is deleted. – yunzen Mar 19 '13 at 11:32
  • it looks like session storage does not behave exactly like session cookies – Walter Tross Mar 19 '13 at 12:31
  • 1
    ... which is good news, because it seems that sessionStorage is not as unpredictable as session cookies. Modern browsers APIs (including mobile browsers) are more likely to focus on html5 recommendations. There's a good chance that sessionStorage has been designed to address the shortcomings of session cookies with modern devices. – marty Mar 19 '13 at 13:38
  • you fiddle does not work, i get `(index):93 Uncaught TypeError: Cannot read property 'get' of undefined` in the console. – Black Apr 12 '16 at 09:46
5

My solution to a similar problem was to use the document.referrer in combination with the cookie. If the user is navigating around within your site then keep using the cookie if it exists, otherwise expire or replace the cookie.

The problem is still there for when the user puts the browser in the background while on your site though. If they resume browsing and just use a link in your site, the cookie will still be used.

aaron
  • 854
  • 2
  • 12
  • 23
4

This problem is not limited to mobile devices. Session cookies may last "forever" also on a desktop browser, if a user constantly chooses to "restore the previous session" (I learned this the hard way).

A client-side solution to limit sessions to one day is the following:

Set two cookies:

  • a (browser-)session cookie, and
  • a cookie that expires in the middle of the user's night (e.g., at 4 am or 5 am), between, e.g., 2 hours and 26 hours from when it is set (in general, it should expire in a window btw. x and x+24 hours)

If EITHER cookie is missing, start a new session and reset them both.

To set the second cookie, you can make use of Date.getTimezoneOffset(). Alternatively, if you are able to reliably geolocate the user so that you have at least a rough estimate of their longitude, you can use the longitude to calculate when the "middle of the user's night" is expected to be (1 hour is 15 degrees of longitude). Two possibilities are: by IP address (knowing the country may not be enough, though: in countries like the USA you need at least the state level), or by using info provided by the CDN, if you use one.

Keep in mind that if something MUST expire after a while (e.g., a session on the server), then you cannot rely on cookies, you must check for expiration server-side too.

Walter Tross
  • 12,237
  • 2
  • 40
  • 64
2

I would ask the user if wants to remember the location. If not set cookies' expiration to servers' timeout. You will give user a choice to pick user experience.

You can try attach to onbeforeunload event and make a post to server to alter cookies' expiration time or if cookie is not secure type then delete it from java script.

jan salawa
  • 1,198
  • 1
  • 8
  • 25
1

This is a bit of a dirty suggestion and by no means fool proof - but I reckon it's worth a mention. I've never had a phone that stayed connected to the internet while idling (they all cut off to conserve battery and whatnot) - and mobile networks recycle IP addresses very quickly.

It may be worth storing the IP address in the session data and - perhaps in conjunction with a last accessed timestamp - destroying/restarting the session if the IP address changes?

Obviously this assumes the client is connected via the mobile network and not wifi.

Emissary
  • 9,954
  • 8
  • 54
  • 65