How to handle session timeout when a device was suspended in an Ajax app? - ajax

It's easy enough to build an Ajax app which checks all responses to make sure they aren't indicative of a session expiry, and if the session has expired automatically log the user out with a friendly "Your session timed out due to inactivity" error message.
But a common occurrence in Ajax applications is that:
User is logged in, happily using app, retrieving data over http with an established http session
User closes laptop
Host times out http session after N minutes
User reopens laptop later on. Ajax app appears alive and well. They click around which is just fine since the app lets them see things they've already loaded.
Then, they click on something that requires data to be loaded, and the data comes back indicating session expiration
The Ajax app kicks them out and says "Your session timed out due to inactivity".
This is really weird to the user because they were not inactive from their point of view.
Now, one possibility is to have Javascript code in the client which uses setTimeout() to periodically (say, every 15 minutes if the session timeout is 30 minutes) trigger a request to the host to ask how much time is left in the session. This periodic check is great because it lets you show them a warning when they are close to timing out, e.g. "You're session will time out in 1 minute unless you do something".
But that doesn't help when the user's machine is suspended. That's because according to all my testing in many different browsers, setTimeout time applies to elapsed running time instead of elapsed real time. That is, if you call setTimeout("alert('hi')",2*60*1000); and then suspend your machine 10 seconds later, wait 5 minutes, and reactivate your machine, you'll have wait 110 more seconds until you get that alert (I have not been able to find definitive documentation of this behavior but it is a demonstrable fact). So that means your period check may not happen for quite after the user's machine resumes.
My solution to this is to, instead of having my periodic check based on on a long setTimeout, instead do a short setTimeout (say, every 5 seconds), and check the elapsed time since the last check using new Date().getTime() to get the actual clock time. This way I am always checking against the real clock, and instead of the client waiting from zero to fifteen minutes before realizing it has timed out after a suspension, at most it will wait about five seconds (plus http response time) to find out.
But I dislike this solution because it relies on a frequent timer based interruption. Is there a smarter way to handle this?

With big sites like facebook, which is rich with interactive updates, you'll find that there is a combination of all sorts different mechanisms. I'd guess that they're doing validation both on API requests and on Push requests (since someone once told me they use push in addition to ajax)
Timeouts: One thing to consider is that if you store session data in a cookie, having that cookie expire is the same as no longer being logged in. Since the cookie is a hashed value of a few things like a user ID, or a timestamp, it is really easy to see that a session is no longer valid on the very first function call to the API.
Long polling: if a site uses long polling in which a connection is opened indefinitely to await a response from the web server, then closing your computer would kill that connection.
However, if they're just doing regular ajax polling with a reoccurring function call via setInterval, then the web server would automatically know whether the user should get data in return based on the timestamp in their hashed cookie, assuming there is one to check. Those are the types of things that get sent in the header.
Some services actually update a database field that stores your timestamp of last activity and then expires if a certain amount of time has elapsed. This is a less efficient way to do it since it keep track of state.
There's really quite a few ways sites do these things.

Related

How often should i make an Ajax request on a timer?

setInterval(function(){
// ajax request here
}, 9000);
I use a script like this to check for new notifications in the database and display them back on the page, giving the fact that for every user this check will be performed every few seconds or every minute i wonder if this can cause any performance issues.
Is it ok to make so many requests to the database or should i check for new notifications some other way?
There are two things you need to consider:
How often are updates needed?
Can the server respond to them that frequently?
The first of those, only you can answer.
The second depends mostly on how much work the server has to do for each request, how many concurrent users you have, and how good the server hardware and network connection are.
The biggest risk with your current approach is that if the server can't respond that frequently, then you will have simultaneous requests in flight. If there is a real performance problem, you could end up with a queue of requests waiting to go out from the browser once you hit the maximum simultaneous HTTP request limit.
You can mitigate this risk by putting setTimeout in the success and error handlers for the request instead of sending them out every 9 seconds regardless.
An alternative approach would be to have the server initiate the sending of data when a notification became available. You could do this using WebSockets.

How exactly do Firebase Analytics handle session duration / timeouts?

I'm implementing some basic usage statistics for the first time in an Android/iOS app using Firebase Analytics, but the docs seem a little ambiguous to me on how exactly session durations are calculated and how sessions are timed out, and the 24-hour cycle for seeing results does not help in understanding by trial-and-error.
I'm only interested in a very simple statistic for now - the time users spend in the app. What exactly happens when the app is "minimised"/"in the background" - does that count as active usage or the same as the app being closed - is not so important right now, but if you have something to add in this regard in the context of the question, please do.
From what I understand such an easy statistic should probably be available out-of-the-box with Firebase Analytics, so I'm currently not using any custom events or anything fancier than simply linking Firebase Analytics into the projects, adding the configuration files, and calling FirebaseAnalytics.getInstance(this); on Android and [FIRApp configure]; on iOS.
I'm seeing first_open, session_start and app_remove events show up in the console as expected, some aggregate session data in the dashboard, etc, and I also know there is a configurable session timeout available.
But what is unclear to me is, when exactly does a user session expire - does Firebase automatically keep it open as long as the app is open, or do I need to make sure to post some artificial "keep-alive" events to prevent user sessions from expiring while a user is still actually using the app.
Assuming the following:
I send no explicit custom events using Firebase, as this is not
explicitly required by the app.
I only touch Firebase once during a single run of the app - initialising it on startup.
The user stays in the app for a long time (let's say 2 hours - much longer than the default 30 minute session timeout), without interacting with it - e.g. reading something, watching a video, etc, none of this generates any events that Firebase can see, but the app prevents the screen from locking, the app remains in foreground.
Will that count as a single 2 hour session for the user? Will it only count as a 30 minute session since the session expires after 30 minutes and no events are generated to keep it alive? Will something else happen?
Bonus question: what happens if the user exits the app for a time shorter/longer than the session timeout?
Bonus bonus question: does something change if instead of exiting from the app, it is simply put into background?
Thanks!
Quick answer: The scenario you describe will result in a single 2-hour session.
Sessions are based on the time that an app's activity is the current activity. There is no need to send events; the period from the time an activity resumes to the time it is suspended is counted as engagement time. At the end of an hour of continuous engagement an engagement event will be logged but this does not end the session. A session expires when there is a continuous period (30 minutes by default) that none of the app's activities is the current activity.
If the user exits the app for a shorter period than the session timeout and then restarts it, the session continues. If the user exits the app for longer than the session timeout, then the session ends. No change between exiting the app and putting it in the background. If it's not the thing the user is looking at, it doesn't count as engagement for the app to be running.

How to increase the timeout period of a web service request in netsuite

I want to increase the 'session timeout', which currently is set to 20 minutes. How can I increase or decrease it by one hour, or in other terms, 60 minutes?
There are a few ways to accomplish what you need, as we ran into the same issue when doing our NetSuite integration.
You can make a dummy search event every couple of min. We searched for a bogus transaction that we knew would never be created, and limited to a date in the distant past and only that date. That way the search would return very quickly with zero results.
Implement SingleSignOn. This is the preferred method. Once you initiate the single sign on, if the session has timed out on you previously you can quickly make a new session using tokens and do not need to ask the user for their username/password again.
We had a service that needed consumed at two different points in the application that did not know about each other. So the way we got around this but still using one service was saving the cookies from the service in a shared location. Then when the service is needed by one of the application they would recreate the service from the cookies. If the service had timed out we would recreate the service and update the cookies. This method became outdated once we implimented SingleSignOn, as then we could just create the service from the tokens as needed, and the tokens were stored in a shared location.
Hope this helped.
There is no standard way that I know of in NetSuite, you could though use a browser plugin to refresh the page or click the home button every 19 mins. Would work if for example the person is AFK.
There is no way to change the web service request timeout period (for sync operations it lasts approx 15 min, then the operation gets terminated on the server side). The general practice for long running operations that takes more than 15 mins is to use async requests.

Setup BOSH so that it allows for users to login without passwords for a long period of time?

I'm just wondering how one could set this up without the BOSH dying. I have the sid, rid, and everything but I was wondering how long i could automatically log people on for the time of lets say a cookie and how is this achieved.
Your answer depends on how long it takes for your BOSH session to timeout. It's usually 60 seconds until it throws away the session.
Just a note- you probably do not want to automatically log in a user, since the proper XMPP flow is not done. Here's a typical flow:
-> Login and establish a BOSH session.
-> Send Presence
---> Server sends a <presence/> packet to all entities in your roster, notifying them that you are available.
---> Server sends a presence probe to all of the entities in your roster's server, getting their current availability.
<- Presence packets come raining down on your session.
-> Request roster items
<- Server sends you a list of items in your roster.
With the approach of using the same session, you skip all of this initialization, which I assume is important to your application, as you will not get presence of any entities until they change their presence. Sending another <presence/> stanza will not send you the current presence of everyone in your roster. So... if that isn't important to you, go ahead and do it. I'm just providing some useful information before you go and implement the thing and find out that there are caveats to your solution.
What worked for us was to use localStorage, and automatically log them in via a "Save my password" button. That makes it simpler and less work. Also, it can be confusing when a user reloads the page and they get logged back in automatically, versus a user closing the page and coming back in 5 minutes to be greeted by the login page. It's just plain confusing.
Good luck!
You can do one of the following as per your need and convenience:
Auto detect about user login status via cookies. Do an http-pre-bind and issue new rid/sid to the user. This will generally be transparent to user on your page.
Instead of issuing new "sid" on every page refresh/reload which can be quite expensive under high traffic, you can pool the underlying xmpp tcp streams. Next time when a user need sid/rid to start again, these can be fetched from the connection manager pooling the sessions.

Session timeout in web applications

The session timeout in web applications typically denotes the idle time - i.e. the period of time when the user doesn't work with the application.
Now, what if there is an automated script written that posts a request every 5 minutes - wouldn't that user's session go on endlessly? This being the case, won't this approach heavily load the application affecting its performance in the long run?
Running an automated call to the server, say via an AJAX request, will keep the session alive. Typically that's the point though. An interesting side effect of this is that if the request happens predictably and regularly, you can use it as a "ping" to determine if the user's browser is still open. If one or two pings are missed, you can close the session earlier and actually free up resources sooner than if you just let the session time out.
Yes, and Yes.
This is why if you're going to write an application for the web, you really want to find a way to implement it without using server side sessions. Usually, you will be able to find ways to implement the same functionality using cookies -- then the session data is client-side so who cares if they stay active permanently.
I did something similar for an application that relies heavily on session data.
What I did was set the IIS timeout to a relatively low number, say 10 minutes, then have a timed AJAX call that pings a blank page every 5 minutes.
This overhead on this is actually fairly low, as all you are doing is requesting a blank page, and if a person closes their browser, the session ends in 10 minutes.
You want to keep session as small as possible. That said, if everyone starts doing that, of course it will load your application, with(out) session. If you think your users are compelled to do that, consider why, as either your application is missing an important feature or is forcing them into something.
Now, regardless of that, if you are expecting lots of users to be active at the same time, so much than a single server won't do, then you would will end up having the session out of process. If the session is in Sql Server, it is just saved data, so in that case we wouldn't be talking about memory usage.
Well... I guess "It Depends" The first question you should ask yourself is whether you even need session.
If you have an automated process, my guess is that you don't really need to use session.
In that case, either turn it off or don't worry about it.
I guess your session table would be a little bit larger, but on the other hand you won't be tearing down and recreating the session. I don't see how this would "heavily load" the application. I suppose it would depend on the application itself and how much memory is used to maintain session state.
It would allow the use's session to go on endlessly, as long as they have their browser open. If need to keep a session alive for an extended period of time, you could also track the sessions via the DB and not in memory.
Also, if you are worried about the indefinite open session, you could implement a timeout from when the session opened and if there is an extended idle time.

Resources