tags:

views:

498

answers:

4

I'm working on an inter-site single-sign-on project and have had a pretty little problem dropped in my lap. When a user logs out of the "parent" site, a particular page needs to be loaded in the popup window containing the "child" site. However, I can't store a reference to the return value of window.open(…), because the user must be allowed to navigate wherever they like on each site before logging out.

This would be easy if I could assume that the child site is always open, as another window.open(…) to the same named window would change its URL. However, the popup cannot be caused to appear if it isn't already open (not all users have access to the child site).

I think this gives me two conflicting scenarios. When the user visits the child site:

  1. User logs in to parent site.
  2. User clicks link for child site
  3. Child site appears in a window named "child_popup".
  4. User browses far and wide in the parent site, forgetting that the child window exists.
  5. User logs out of parent site.
  6. Child popup is redirected to the child site's logout page.

And when the user does not or cannot visit the child site:

  1. User logs in to parent site.
  2. User browses far and wide in the parent site.
  3. User logs out of the parent site.
  4. No popup should appear!

So my limitations are:

  • I cannot store a reference to the window in JS, as the user may navigate to any number of pages between visiting the child site and logging out.
  • I have zero control over the contents of the child site (my employer runs the parent site).
  • The parent site cannot be converted to frames to provide a "global" JS scope. :-)

I was not able to find any relevant resources on Google or SO. Is there a way to accomplish this?

A: 

Use sessions to store the state of the popup.

When the user clicks a link to open the child site, you need do do an asyncronous javascript call to the parent server that records this user has opened a window to the child site. OR have the link open a page that stores the following session info and returns a Location: header.

(Notice I am using php, $_SESSION[...] is a user specific array of data stored between requests)

$_SESSION['inChildSite'] = true;

When the user logs out of the parent site, this value is checked again, either by an asycnronous javascript call, or by the logout script.

if ($_SESSION['inChildSite'] ==true ) 
     echo "<script>window.open(...)</script>"

Then display the logout child window. Make sure you unset your session variable when the logout happens.

Voila, profit.

Byron Whitlock
Unfortunately, I don't have access to server-side session data (read *or* write). Essentially, I am being required to do this in pure JS. I'm currently pushing back to see if I can get a more reasonable set of requirements.
Ben Blank
+1  A: 

Yes, you can, subject to one important restriction.

It hinges on the following behaviour:

  1. the first 2 parameters of window.open are a URL and a window name
  2. window.open returns a reference to a window
  3. if a window is already open with the specified name, then a reference to that window is returned rather than a reference to a new window
  4. If the URL is NULL, an existing window won't navigate to a new page

This means that you can get a reference to an existing window, without losing the page that window has open. However, if a window doesn't exist with that name it will be opened.

We used this approach at http://carbonlogic.co.uk/ but because of a Flash Player issue the contents of the popup aren't working properly at the moment

Gareth
That's really neat trick, but I'm afraid it's actually the opposite of what we need. I *do* want the page to change if the window is open; I *don't* want a new window to pop up if it isn't. :-/
Ben Blank
A: 

It sounds like you are in control of the contents of the child window... If so, you could try setting "window.opener.some_attr = true", when you first load the child window.

Thus your code in the parent window could do "if (window.some_attr) window.open(...)" or the converse "if (!window.some_attr) alert('no access')..."

Mathew
A: 

We weren't able to find a way to detect whether the child-site window is still open, but we came up with a workaround which satisfied our business requirements folks:

  1. Set cookie A from parent site when launching child popup.
  2. Set cookie B from child site on every page load.
  3. Clear cookie B from child site on every page unload.
  4. When logging out of parent site:
    1. If cookie A is set, clear it and close local connection to child site.
    2. If cookie B is set, clear it and open child logout page in popup.
Ben Blank