15

I'm working on a web app using PHP on Apache. $_SESSION variables are used quite a bit for the information that must persist across pages.

We need each user to be able to open multiple concurrent sessions, either as new tabs or new windows, depending on their choice of browser. Right now when a user opens an addition tab or window and goes to the site the existing session is adopted. How can I prevent this so that the user must (or may) log in and start a new session, without it interfering with any existing session(s) they already have open?

Our temporary workaround is to use multiple browsers (IE and FF) but that's obviously not a very desirable way of doing things.

John Gardeniers
  • 370
  • 1
  • 2
  • 15
  • Not possible. You need to write your own session handling script, and pass if through appended to every URL. –  May 20 '11 at 03:23
  • 5
    `pass if through appended to every URL` What could possibly go wrong? – a coder Jun 07 '13 at 15:12

5 Answers5

8

The behavior you describe opposes the concept of a browser session. Why would a user want more than one session? Is it a matter of user access controls needing to be enforced? If so, assign users to logical groups and grant permissions to specific groups. Do users need to perform some action on behalf of other users? If so, design the website around that concept instead of trying to create multiple sessions for a single user.

If you really have to do this, you could do something horrible like pass along a query parameter (very insecure!) between pages to act as a session ID, bypassing the actual $_SESSION altogether and managing your own concept of a session. Again, this is not normal and will only lead to headaches/security issues in the future.

Dave
  • 777
  • 6
  • 9
  • 2
    The reason we have this need is due to the way the application is used. e.g. A sales person may need to have more than one order entry screen open at any given time. This might be because one customer needs to be temporarily handed over to another staff member for various reasons. The sales person then needs to be able to start a new order for the next person in the queue, without it interfering with order that's already open, which will be finished when the original customer gets handed back. With the old system this was done by opening multiple copies of the application (not web based). – John Gardeniers May 20 '11 at 03:53
  • 12
    Ah, I understand now. :) You could change the way your site works to not hold the salesperson's current order in the session. Instead, you could use a more RESTful approach [http://www.xml.com/pub/a/2004/08/11/rest.html], where the ID of the order the salesperson is updating is part of the web page's URL. That way, they could open two tabs/windows and modify two orders, and the session would be taken completely out of the picture. – Dave May 20 '11 at 04:11
  • 2
    Answer accepted for the above comment, rather than the answer itself. – John Gardeniers May 23 '11 at 11:10
2

Non-Atomic Concurrent Session Management access can be simulated with the following pseudo coded logic:

function main(){
  $locker = new SessionLocking();
  /** read elements the $_SESSION "cached" copy. **/
  $var1 = $_SESSION['var1'];
  $var2 = $_SESSION['var2'];
  /** Pseudo Atomic Read **/
  $locker->lock(); //session is locked against concurrent access.
  $var3 = $_SESSION['var3'];
  $locker->unlock(); //session is committed to disk (or other) and can be accessed by another script.
  /** Psuedo Atomic Write **/
  $locker->lock(); //session is locked against concurrent access.
  $_SESSION['var4'] = "Some new value";
  $locker->unlock(); //session is committed to disk (or other) and can be accessed by another script
}

CLASS SessionLocking {

private static $lockCounter=0;
private static $isLoaded=false;

function __constructor(){
  if (!self::$isLoaded) load();
}

private function load(){
 $this->lock();
 $this->unlock();
}

private function lock(){
  if ($lockCounter<1) try {session_start();} Catch(){}
  $lockCounter++; 
}

private function unlock(){
  if ($lockCount<1) return;
  $lockCounter--;
  if ($lockCounter<1) try {session_write_close();} Catch(){}
}
}
1

This would be very difficult to do, if at all possible.

Sessions should not have to worry about which tab they are in.

Also, what happens if session 1 in tab 1 opens a new window? Is it a new session?

alex
  • 438,662
  • 188
  • 837
  • 957
  • This is the best writeup I could find on the matter: http://www.php.net/manual/en/ref.session.php#74557 – onteria_ May 20 '11 at 03:09
  • @onteria_ this seems primed for abuse: `So, every link, form, header() and Javascript code will forward the SESSION_NAME value to the next script and it will know which is the session it must use.` – a coder Jun 07 '13 at 14:45
0

Knowing it's a very late answer ...

As a developer, I usually need to simultaneously test the interface of different user types (Administrator, Registered, Visitor, etc.). Firefox browser has a "Multi-Account Containers" add-on that, among other things, keeps cookies separated by container. As many containers as required may be created and tabs opened inside each one of them. Each set of contained tabs share cookies but not across containers. The browser will be working with different independent "PHPSESSID" (or however you named the cookie), thus being able to handle multiple simultaneous sessions.

There are other extensions and considerations, such as special bookmarks, etc. but they are beyond the scope of the question here.

Dharman
  • 21,838
  • 18
  • 57
  • 107
-3

Here is a way to do that:

-First disable session cookies in php.ini with:

session.use_cookies = 0

This makes sure that cookies are not used to pass the session id.

-then Make sure you generate all your URLs with the session id included ( you get it through function session_id() e.g.:

print "<a href= \"http://www.example.com/".session_id()."&showlist=1\">show list</a>";