会话显示突然的行为

时间:2016-05-06 13:05:43

标签: php session cookies logout

我的php会话显示异常行为。情况:

  • 用户登录(https://example.com)应用程序
  • 会话Cookie有效期设置为7天。 (从浏览器cookie生命周期验证)
  • 用户移至其他域(不含https
  • 当用户通过单击应用程序链接尝试在某个时间后返回时,会话将被破坏。
  • 行为突然。有时它会保持有效。

以下是我开始会话的方式:

if(!$this->session_manager_issession_set()) {
            $this->set_ini_config();
            session_name($this->session_manager_name);
            session_set_cookie_params($this->session_cookie_life, "/"); //Required for browser cookie cleanup
}

session_start();

if(empty($_SESSION))
    {
        $output['status']   =   false;
    }
    else{
       // Fetch the variables
    }

public function session_manager_issession_set(){
        $output =   true;

        $session_status =   session_status();
        switch($session_status){
            case PHP_SESSION_ACTIVE :

            break;
            default:
                $output =   false;
        }

        return $output;
    }

private function set_ini_config(){
    $output =   true;

    ini_set('session.gc_probability', 1);   //If session expires then ensure that session is flushed and cleared at all instances
    ini_set('session.gc_divisor', 100);     //If session expires then ensure that session is flushed and cleared at all instances

    ini_set('session.gc_maxlifetime', 7*24*60*60);  //MAx life of session cookie
    ini_set('session.cookie_secure', true);

    return $output;
}

这可能是什么原因?我是否以错误的方式实施了会话?

5 个答案:

答案 0 :(得分:1)

首先,你的函数session_manager_issession_set()基本上会检查会话是否未启动(session_status() != PHP_SESSION_ACTIVE),但是你开始会话时忽略会话可能已经运行的事实。

如果会话名称对您很重要,则必须强制执行:

if ($this->session_manager_issession_set()) {
    // session has already started, but we haven't set a name for it!
    throw new Exception("Session started prematurely");
}

// all fine, session isn't running; continue with setup
$this->set_ini_config();
session_name($this->session_manager_name);
session_set_cookie_params($this->session_cookie_life, "/");
// and finally start the session
session_start();

由于session.name设置了一个用于存储会话ID的cookie的名称,并且您使用了非默认名称,因此我猜测有些事情会在您开始之前启动会话,因此您无法看到幸运的是,您之前开始与会话相关的数据。

其他选项是保留所有代码,并仅使用

删除一行
session_name($this->session_manager_name); 

如果有帮助,那我一定是对的。

答案 1 :(得分:1)

在检查任何会话检查参数之前, 从基础开始,例如从

开始
print_r($_SESSION);

这将只输出你在那里的Session变量,就像你看到服务器记得会话及其变量一样,

接下来,我认为这里的一些答案是针对某些事情的, 你检查你的会话是否已经开始,但你想检查一个会话是否还活着(不一样)......

因此,如果您知道会话变量中的某个键将始终存在,那么只需使用以下命令进行检查:

if(isset($_SESSION['your_key'])) {
// Your code if session has been made already
}

我知道这看起来很简单,但是当你试图弄清楚你的错误时,嘿回到代码的基础并不是必然的坏事:) 所以试试这个,如果以上两个都适合你,那么即使你的Session变量是完整的,你也会使用一些错误的错误语句......:)

答案 2 :(得分:0)

正如您在问题和评论中提到的,用户不仅移动到不同的域,而且移动到另一个服务器(因此从httphttps的更改更有意义给我们读者)。 $_SESSION是一个超级全局,在服务器上保存,因此更改服务器是导致$_SESSION值被销毁的最可能原因。

简而言之,它可能仍然存在,但由于您尝试从其他服务器访问它,服务器无法找到它,因此导致您(或服务器)相信它被摧毁了(因为它生活在启动会话的原始服务器上)。这可以解释为什么它有时会起作用,有时候不起作用,因为你可以在服务器之间切换,有时候你很幸运,并且在最初创建会话的同一台服务器上。

答案 3 :(得分:0)

请在php.net manual

了解session.cookie_secure

这会将您的会话cookie仅限于安全(所以https)连接。从https切换到http

时导致会话丢失

答案 4 :(得分:0)

Rafael说你应该尝试用更简单的代码库重新创建和解决问题是正确的。您还应该检测代码以找出浏览器返回的

  

我是否以错误的方式实施了会话?

代码难以阅读,不恰当地使用switch语句,无缘无故地覆盖系统配置,以及许多其他奇怪的事情。尤其是这是一个特别不寻常的用例,你应该要求会话长时间处于活动状态(#34;记住我"功能非常与会话不同)。一旦你舔掉会话持久性问题,你可能想要阅读一些PHP风格标准并访问codereview.stackexchange.com