更改网络时,PHP SESSION(使用myPajamas登录脚本)无法正常工作

问题描述:

I have looked everywhere on the web, and the nuances of SESSION variables need some clarification for me.

I have a website that sets a session variable (I assume it also sets a cookie defining what the session id is? Not sure how that works), and all works perfectly. What I've found when roaming(using wifi) by cellphone, that whenever the phone switches wifi networks, the browser seems to be unable to access the session anymore until that window/tab is closed and reopened.

From what I've read the following apply, please clarify for me:

  1. When browser windows are closed, the session cookie is destroyed, thus when I reopen it, a new cookie is created attached to the new session id. Thus allowing the session to work properly again?

  2. If the network is switched, the server creates a new session id, but because the browser window wasn't closed, the old session cookie wasn't destroyed, and the browser tries to manipulate an expired session id (the old one the session cookie contains)? No idea if this is true, I have read a ridiculous number of pages on this and I can't find anything specific. But this is the impression I get. I have seen so many warning about session_regenerate_id() that I am very nervous about using it...

Any help on details about this, or ways to fix it would be extremely helpful. I am at my wit's end...

UPDATE

I am using a mypajamas script to facilitate logins. The sessions are created normally. However, after looking through the code, I found a place where a session variable is set for the $_SERVER['REMOTE_ADDR'] and $_SERVER['HTTP_USER_AGENT'] values. They are then cross referenced to ensure it's the same user on the same browser on the same IP. It was done to prevent multi-source attacks (make a hijack unlikely). The problem is when using mobile browsers, or dynamic IP's the IP can definitely change, and authentication fails.

I can't believe I couldn't figure this out, I spent hours looking for issues regarding session id's changing.

Hopefully it helps someone with a similar issue in the future. And a sincere appreciation to all who read this post, your guidance in the comments definitely helped me troubleshoot this.

EDITED CODE

class.mypajamas.php

From:

function check_ipau() { // user visits again... but is it really him? check values set above (by get_session())
    if( $_SESSION['auth'.$this->_unique_id]['ip'] == $_SERVER['REMOTE_ADDR']
    &&  $_SESSION['auth'.$this->_unique_id]['ua'] == $_SERVER['HTTP_USER_AGENT']) {
        // session data is correct -> user did not "change" ip-address or user agent (aka; hijack is unlikely)
        return true;

    }
    else {
        return false;
    }
}

To:

function check_ipau() { // user visits again... but is it really him? check values set above (by get_session())
    /*if(   $_SESSION['auth'.$this->_unique_id]['ip'] == $_SERVER['REMOTE_ADDR']
    &&  $_SESSION['auth'.$this->_unique_id]['ua'] == $_SERVER['HTTP_USER_AGENT']) {
        // session data is correct -> user did not "change" ip-address or user agent (aka; hijack is unlikely)
        */
        return true;
        /*
    }
    else {
        return false;
    }*/
}

First of all, session variables are actually cookies.

1) Session cookies have a lifetime. If your code isn't specifying the lifetime, then the value defaults to whatever is in your php configuration. Do a phpinfo(); and look for session.cookie_lifetime, which is a value in seconds. A value of 0 means the cookie expires when the browser window is closed.

2) If your code is using boilerplate PHP Session handling, then it's unlikely that the issue is related to the user's ip address changing. PHP sessions do not store client ips, and as long as the application you're connecting to has the same domain name/public ip across both networks, then you should be fine. (see PHP Session Cookies fail with users changing IP)

It's possible that there may be some added Session handling that stores the client's IP, but that would have to be custom coded and not based on any built-in functionality.

(based on your edit, this was, in fact the case.)

If you're accessing the same url on network A and on network B, then there is no reason why the session will change / be affected by the network switch. If you have to close the browser window down, and find that your session data is gone, then the problem simply lies in setting the lifetime of the session cookie to be a value other than 0. Place the following line before session_start():

session_set_cookie_params(X);

Where X is a value in seconds after which the cookie will expire. Keep in mind that if you call the aforementioned code before every instance of session_start(); then the cookie will effectively never expire since every single page will be resetting that counter ahead by one hour.

Sessions are server-side only. Unfortunately, if you are coming from a different network address the session will not be valid.

A good practice if you want to retain session values is to create your own cookies, so that you know someone was once authenticated/had a valid session. You then first check if the session values are set, if not check for that cookie. If that cookie exists and has a good value, you can re-set the session value to that of the cookie (or just set the session as you would upon authentication). If there is no session and no cookie then the session is presumed to be non-existent.