views:

1825

answers:

9

I'm wondering if it is possible to determine if a user already has a web browser open to the web application I'm working on. It seems that they can open several instances of the same web app and click on buttons to read information that they have used before to enter into an input screen that they're currently working on.

What happens though is that it seems to screw up Session variables and then the user will update their previous work with their new work. Or they will delete their previous work all together or who knows...

EDIT I have seen this done before with online banking web applications. If you are already logged in, the new window will kindly tell you that you already have the app open. In my case, the user does not need to log in.

Is there a simple way to determine if they already have a browser window open to the web application and if so, just close the browser or display a different page to let them know they can only have 1 open at a time?

Thanks

A: 

You could check if a the user has more than one active session. This might work, but could be problematic since there's no good way to determine if a session is really active or not.

Jason
A: 

I'd like to know this too.

Pressing Ctrl-N in Internet Explorer 6 doesn't seem to trigger anything inside the DOM or on the network that allows you to take action to the duplication of the window.

I've tried a couple of things like using Onload event on the body, nothing.

Tommy
This is not a forum, if you want to add to the question, do it in the comments of the question.
Hassan Syed
A: 

I use the trick of opening a new window with a specific ID and always make sure that any page will open always use that window.

The down side, they must have their popup blocker turned off for you site. It works well for company sites.

if (useOwnWindow && window.name != 'YourAPP'){
    var w = window.open(document.location, 'YourAPP', 'toolbar=no,status=yes,resizable=yes,scrollbars=yes');
    if (w==null){
        alert("Please turn off your pop-up blocker");
    }else{
        window.open('','_parent','');
        self.opener="";
        self.close();
    }
 }

Note the useOwnWindow flag if used by developers so we can open it multiple times

Glennular
+3  A: 

Is there a simple way to determine if they already have a browser window open to the web application and if so, just close the browser or display a different page to let them know they can only have 1 open at a time?

In short, No.
Without writing some kind of activeX control, there is no code you could write that could stop the user from opening a (seperate instance of) IE/FF etc and having one instance detect the other.

Adam Naylor
+3  A: 

You could assign a 'mini-session' ID to each instance of the input form, then use AJAX to ping the server with that ID. If the user tries to request the same form when there's an active ID, it should display an error message. If the server doesn't hear the ping for a certain amount of time, expire the mini-session. (This is basically a very simple locking strategy)

Justin Voss
+1  A: 

I would suggest you hash the ViewState for the page and store it in a session variable before it is returned as the Response.

Then for a Request first check the hash of the returned ViewState against the one you have in the session variable and if they don't match don't process any changes on the page and display a notice to your user or redirect them to an error page.

The two methods of the Page class you will want to override are;

protected override object LoadPageStateFromPersistenceMedium()

protected override void SavePageStateToPersistenceMedium(object viewState)
Dave Anderson
Uhm ... wouldn't two separate logins result in two separate session caches. The ASP.Net session cache has no concept of users.
PeterR
+3  A: 

Firstly, no there isn't, and secondly, you shouldn't try.

The pop-up window strategy won't work (and will annoy users). I have my browser set to 'Open windows as Tabs', and I choose whether to split one off into another window. Or in some cases, whether to run a different browser -- not just another instance of the same one -- to display another page on the same site.

Conversely, the mini-session ID will fail because the server can't keep track of whether a request is from the same user as an existing session. Several people may be using the same machine, even with the same username; or one person may have several separate login sessions, on one or several machines.

Just sort out your protocol vs. 'Session' variables and make sure that the last committed changes are the ones that persist.

+1  A: 

We have implemented a solution to this problem on the slicethepie.com. Users (or "scouts") are only allowed to have one browser window open at a time to ensure they listen to the music they are being paid to review.

When a scout requests the first track to review in their scouting session we set a new Guid on their account and return this "key" along with the details of the track they're being given to review. It happens that the recipient of this key is a flash movie, but it doesn't have to be. The key is re-submitted along with the scout's review, and we check to see if it matches the saved key. If it doesn't they've started a new scouting session in a new window.

I'm not implying this method is foolproof, but it could be adapted to your needs quite easily.

Paul Suart
my users do not have accounts, but this concept is interesting. I guess my biggest problem implementing this would to be able to track if the user has left and re-opened a new window or if they have never left and opened another window.
Eppz
+1  A: 

As others has mentioned, you can't prevent the user from starting a new session without resorting to ActiveX or other nastiness. The basic problem is that there is no way for you to know whether a user closed the old browser window or left it open.

What you can do however, is to invalidate the previous session as soon as the user logs into a new (A bit similar to how may Instant Messaging clients behave).

On each login, assign a new GUID to the user in your database. Also store this GUID in the session cache (No need to ship it back and forth to the pages, which won't work for GET requests anyway). On each page request, compare the GUID assigned to the user in the database with the GUID in the session cache. If they don't match, return a "You have logged in from somewhere else" response.

Update I was a bit too fast on the trigger. This doesn't prevent the scenario where the user opens multiple tabs/windows within the same browser process. So you would have to combine this solution with Dave Anderson suggestion for storing a ViewState hash (or simply a GUID) so that only the last served page in a session is allowed to post back.

Security Update Also, you can only rely on this framework as a convenience to the user since it's not secure. Any half decent hacker will be able to circumvent these measures.

PeterR