0

我有一个奇怪的问题会话没有保存到全局变量,但它们正确保存到我的数据库中。我有一个设置会话的 ldap auth 脚本,我登录了,但是当我刷新或转到不同的页面时,它会丢失变量并且它让我发疯这里是减去 ldap_auth.php 的脚本

<?
function sess_open($save_path, $session_name){
        $_SERVER['SessionDB']->connect();
        if ($_SERVER['SessionDB']->sess) return true;
        else return false;
}

function sess_close(){
        $_SERVER['SessionDB']->disconnect();
}

function sess_read($key){
        global $SESS_LIFE;
        $_SERVER['SessionDB']->Query('UPDATE Sessions SET Expiry="' . (time() + $SESS_LIFE) . '" WHERE SessionID="' . $key . '" AND Expiry >= "' . time() . '"');
        $Value = $_SERVER['SessionDB']->oQuery('SELECT Value FROM Sessions WHERE SessionID = "' . $key . '" AND Expiry >= ' . time());
        if ($Value) return $Value;
        else return '';
}

function sess_write($key, $val){
        global $SESS_LIFE;
        $Expiry = time() + $SESS_LIFE;
        $Value = addslashes($val);
        if (!$qid = $_SERVER['SessionDB']->Query('INSERT INTO Sessions VALUES ("' . $key . '", ' . $Expiry . ', "' . $Value . '")'))
                $qid = $_SERVER['SessionDB']->Query('UPDATE Sessions SET Expiry = ' . $Expiry . ', Value = "' . $Value . '" WHERE SessionID = "' . $key . '" AND Expiry > ' . time());

        return $qid;
}

function sess_destroy($key){
        return $_SERVER['SessionDB']->Query('DELETE FROM Sessions WHERE SessionID = "' . $key . '"');
}

function sess_gc($maxlifetime){
        return $_SERVER['SessionDB']->Query('DELETE FROM Sessions WHERE Expiry < ' . time());
}

$SESS_LIFE = get_cfg_var("session.gc_maxlifetime");
ini_set("session.save_handler", "user");
session_set_save_handler("sess_open", "sess_close", "sess_read", "sess_write", "sess_destroy", "sess_gc");

// We want a seperate one in $_SERVER['SessionDB']
$_SERVER['SessionDB'] = new mysql_db();

// Set this information appropriately based on what's in
// our configuration file
$_SERVER['SessionDB']->Hostname = $config->dbHost;
$_SERVER['SessionDB']->Username = $config->dbUser;
$_SERVER['SessionDB']->Password = $config->dbPass;
$_SERVER['SessionDB']->Database = $config->dbName;

session_start();
foreach ($_SESSION as $key=>$value)
        if (is_string($value))
                $_SESSION[$key] = trim($value);

function murder_session(){
//      session_destroy();
//      unset($_SESSION);
}
?>

这是login.php

<?

// check to see if user is logging out
if(isset($_GET['out'])) {
   // destroy session
    session_unset();
    unset($_SESSION['user'],$_SESSION['access']);
    session_destroy();
}

// check to see if login form has been submitted
if(isset($_POST['login_Username'])){
    // run information through authenticator
    if(authenticate($_POST['login_Username'],$_POST['login_Password']))
    {
        // authentication passed

    } else {
        // authentication failed
        $error = 1;
    }
}

// output error to user
if (isset($error)) nice_death("Login failed: Incorrect user name, password, or rights");

// output logout success
if (isset($_GET['out'])) nice_exit("Logout successful");
?>

这是包含文件,其中包括它们的加载顺序

// We prefer to use MySQL for our sessions instead of files in /tmp
// for (somewhat obvious) security reasons. Our functions to handle this
// are in here.
require_once($inc_dir . 'session.inc');

// Let's see if the user is trying to log in. We do this here because
// the login form is displayed on all pages until the user logs in.
require_once($inc_dir . 'ldap_auth.php');
require_once($inc_dir . 'login.inc');

这是ldap脚本

<?
function authenticate($user, $password) {
    // Active Directory server
    $ldap_host = "x.x.x.x";

    // Active Directory DN
    $ldap_dn = "Here is the long LDAP String";

    // Domain, for purposes of constructing $user
    $ldap_usr_dom = "@here.local";

    // connect to active directory
    $ldap = ldap_connect($ldap_host)
        or die("Couldn't connect to LDAP Server");

        $x = explode('.', $user);
        $user = $x[0] . ' ' . $x[1];

    $dn = "cn=".$user.",";

    // verify user and password
    if($bind = @ldap_bind($ldap, $dn . $ldap_dn, $password)) {
        // valid
        // check presence in groups
        $filter = "(cn=" . $user . ")";
        $attr = array("memberof");
        $result = ldap_search($ldap, $ldap_dn, $filter, $attr) or exit("Unable to search LDAP server");
        $entries = ldap_get_entries($ldap, $result);
        ldap_unbind($ldap);


        $_SESSION['user'] = $user;
       // $_SESSION['access'] = $access;
        $_SESSION['LoggedIn'] = true;

        return true;
    } else {
        // invalid name or password
        return false;
    }
}
?>
4

2 回答 2

0

好的,所以我发现这是一种愚蠢的方式,当另一种方式适用于数据库中的用户表时,我必须这样做。所以这是适用于用户表但不适用于 LDAP 脚本的旧版本

function sess_write($key, $val){
        global $SESS_LIFE, $sess_db;
        $Expiry = time() + $SESS_LIFE;
        $Value = addslashes($val);
        if (!$qid = $sess_db->Query('INSERT INTO Sessions VALUES ("' . $key . '", ' . $Expiry . ', "' . $Value . '")'))
                $qid = $sess_db->Query('UPDATE Sessions SET Expiry = ' . $Expiry . ', Value = "' . $Value . '" WHERE SessionID = "' . $key . '"
 AND Expiry > ' . time());

        return $qid;
}

这是我写它的新方式

function sess_write($key, $val){
        global $SESS_LIFE, $sess_db;
        $Expiry = time() + $SESS_LIFE;
        $Value = addslashes($val);

        if (!$qid = $sess_db->rQuery('SELECT * FROM Sessions WHERE SessionID = "'.$key.'" AND Expiry >=' . time())) {
                $sess_db->Query('INSERT INTO Sessions (SessionID,Expiry,Value) VALUES ("' . $key . '", ' . $Expiry . ', "' . $Value . '")');
        } else {
                $sess_db->Query('UPDATE Sessions SET Expiry = ' . $Expiry . ', Value = "' . $Value . '" WHERE SessionID = "' . $key . '"');
                if ($sess_db->Error()) die($sess_db->Error());
        }
        return $qid;
}

我仍然不明白为什么一个可以很好地使用用户表,但另一种方式可以完美地工作......

于 2013-06-12T02:04:45.313 回答
0

那是因为您的 LDAP/登录脚本是在会话脚本和session_start()调用之前启动的,即它获取 LDAP 值,将它们正确保存到您的数据库中并且您的登录有效,但是由于会话尚未启动,因此放置的内容$_SESSION是很快被下一个请求忘记了。

或者,如果会话正常,您的会话cookie 可能设置错误(设置为不同的路径或域,或过期时间太短,或任何其他错误),但可能性较小。

于 2013-06-11T01:14:42.043 回答