PHP多个会话变量,登录检查时访问空会话

PHP多个会话变量,登录检查时访问空会话,php,security,session,login,Php,Security,Session,Login,好的,到现在为止,我还没有开玩笑,我花了一周的时间弄明白了这一点,最后把范围缩小到创建多个会话变量,其中只有1个是我需要的数据,其余的都是空的。当然session_regenerate_id(true)应该已经处理了它,但只是部分地,有了它我得到了3个session变量,没有它我得到了6个 这是代码,希望你的智慧和经验的人可能会启发我,以便如何解决这个问题。 这是我的登录主界面,在这里输入凭据 <?php include_once 'includes/db_connect.php'

好的,到现在为止,我还没有开玩笑,我花了一周的时间弄明白了这一点,最后把范围缩小到创建多个会话变量,其中只有1个是我需要的数据,其余的都是空的。当然session_regenerate_id(true)应该已经处理了它,但只是部分地,有了它我得到了3个session变量,没有它我得到了6个

这是代码,希望你的智慧和经验的人可能会启发我,以便如何解决这个问题。 这是我的登录主界面,在这里输入凭据

    <?php
include_once 'includes/db_connect.php';
include_once 'includes/functions.php';
sec_session_start();


if (login_check($mysqli) == true) {
    $logged = 'in';
} else {
    $logged = 'out';
}
?>
<!DOCTYPE html>
<html>
    <head>
        <title>Login Seguro: Log In</title>
        <script type="text/JavaScript" src="js/forms.js"></script> 
        <script type="text/JavaScript" src="js/sha512.js"></script> 
    </head>
    <body>
        <?php
        if (isset($_GET['error'])) {
            echo '<p class="error">Error en el Inicio de Sesion!</p>';
        }
        ?> 
        <form action="includes/process_login.php" method="post" name="login_form">                      
            Usuario: <input type="text" name="Usuario" />
            Password: <input type="password" 
                             name="password" 
                             id="password"/>
            <input type="button" 
                   value="Login" 
                   onclick="formhash(this.form, this.form.password);" /> 
        </form>

<?php
        if (login_check($mysqli) == true) {
                        echo '<p>Actualmente Logueado ' . $logged . ' as ' . htmlentities($_SESSION['username']) . '.</p>';

            echo '<p>¿Cambiar de Usuario? <a href="includes/logout.php">Log out</a>.</p>';
        } else {
                        echo '<p>Actualmente Logueado ' . $logged . '.</p>';
                        echo "<p>Si no cuentas con Login, Favor de <a href='register.php'> Registrase </a></p>";
                }
?>      
    </body>
</html>

登录Seguro:登录
乌萨里奥:
密码:
哪个重定向到进程\ u登录

<?php
include_once 'db_connect.php';
include_once 'functions.php';
#php debugging
#Start buffering the output. Not required if output_buffering is set on in php.ini file
#get a firePHP variable reference
#php debuggin
sec_session_start(); // Our custom secure way of starting a PHP session.


if (isset($_POST['Usuario'], $_POST['p'])) {
    $Usuario = $_POST['Usuario'];
    $Contraseña = $_POST['p']; // The hashed password.
    if (login($Usuario, $Contraseña, $mysqli) == true) {
        header('Location:../protected_page.php');
        exit();
    } else {
        // Login failed 
        header('Location: ../index.php?error=1');

    }
} else {
    // The correct POST variables were not sent to this page. 
    echo 'Invalid Request';
}

安全登录:受保护页面
欢迎光临

这是一个受保护的页面示例。若要访问此页面,请单击“用户” 必须登录。在某个阶段,我们还将检查 用户,因此页面将能够确定用户的类型 授权访问该页面。

回到

您无权访问此页面。请

使用此登录文件的功能,该文件按预期工作,具有自定义安全会话启动,这可能是导致问题的原因

<?php
include_once 'psl-config.php';

function sec_session_start() {
    $session_name = 'sec_session_id';   // Set a custom session name
    $secure = true;
    // This stops JavaScript being able to access the session id.
    $httponly = true;
    // Forces sessions to only use cookies.
    if (ini_set('session.use_only_cookies', 1) === FALSE) {
        header("Location: ../error.php?err=Could not initiate a safe session (ini_set)");
        exit();
    }
    // Gets current cookies params.
    $cookieParams = session_get_cookie_params();
    session_set_cookie_params($cookieParams["lifetime"],
        $cookieParams["path"], 
        $cookieParams["domain"], 
        $secure,
        $httponly);
    // Sets the session name to the one set above.
    session_name($session_name);
    session_start();            // Start the PHP session 
    session_regenerate_id(true) // regenerated the session, delete the old one. 
}

function login($Usuario, $Contraseña, $mysqli) {


    // Using prepared statements means that SQL injection is not possible. 
    if ($stmt = $mysqli->prepare("SELECT RFC, Usuario, Contrasena 
        FROM empleado
       WHERE Usuario = ?
        LIMIT 1")) {
        $stmt->bind_param('s', $Usuario);  // Bind "$email" to parameter.
        $stmt->execute();    // Execute the prepared query.
        $stmt->store_result();

        // get variables from result.
        $stmt->bind_result($RFC, $username, $db_password);
        $stmt->fetch();

        if ($stmt->num_rows == 1) {
            // If the user exists we check if the account is locked
            // from too many login attempts 

            if (checkbrute($RFC, $mysqli) == true) {
                // Account is locked 
                // Send an email to user saying their account is locked
                return false;
            } else {
                // Check if the password in the database matches
                // the password the user submitted. We are using
                // the password_verify function to avoid timing attacks.                         
                if ($Contraseña==$db_password) {
                    // Password is correct!
                    // Get the user-agent string of the user.
                    $user_browser = $_SERVER['HTTP_USER_AGENT'];
                    // XSS protection as we might print this value
                    $RFC = preg_replace("/[^0-9]+/", "", $RFC);
                    $_SESSION['user_id'] = $RFC;
                    // XSS protection as we might print this value
                    $username = preg_replace("/[^a-zA-Z0-9_\-]+/", 
                                                                "", 
                                                                $username);
                    $_SESSION['username'] = $username;
                    $_SESSION['login_string'] = hash('sha512', 
                              $db_password . $user_browser);
                    // Login successful.
                    return true;
                } else {
                    // Password is not correct
                    // We record this attempt in the database
                    $now = time();
                    $mysqli->query("INSERT INTO registo_login(user_id, Tiempo)
                                    VALUES ('$RFC', '$now')");
                    return false;
                }
            }
        } else {
            // No user exists.
            return false;
        }
    }
}

function checkbrute($RFC, $mysqli) {
    // Get timestamp of current time 
    $now = time();

    // All login attempts are counted from the past 2 hours. 
    $valid_attempts = $now - (2 * 60 * 60);

    if ($stmt = $mysqli->prepare("SELECT Tiempo 
                             FROM registro_login 
                             WHERE RFC = ? 
                            AND Tiempo > '$valid_attempts'")) {
        $stmt->bind_param('i', $RFC);

        // Execute the prepared query. 
        $stmt->execute();
        $stmt->store_result();

        // If there have been more than 5 failed logins 
        if ($stmt->num_rows > 5) {
            return true;
        } else {
            return false;
        }
    }
}

function login_check($mysqli) {
    // Check if all session variables are set 
    if (isset($_SESSION['user_id'], 
                        $_SESSION['username'], 
                        $_SESSION['login_string'])) {
        filelog("yay");

        $RFC = $_SESSION['user_id'];
        $login_string = $_SESSION['login_string'];
        $username = $_SESSION['username'];

        // Get the user-agent string of the user.
        $user_browser = $_SERVER['HTTP_USER_AGENT'];

        if ($stmt = $mysqli->prepare("SELECT Contrasena 
                                      FROM empleados 
                                      WHERE RFC = ? LIMIT 1")) {
            // Bind "$RFC" to parameter. 
            $stmt->bind_param('i', $RFC);
            $stmt->execute();   // Execute the prepared query.
            $stmt->store_result();

            if ($stmt->num_rows == 1) {
                // If the user exists get variables from result.
                $stmt->bind_result($Contraseña);
                $stmt->fetch();
                $login_check = hash('sha512', $Contraseña . $user_browser);

                if (hash_equals($login_check, $login_string) ){
                    // Logged In!!!! 
                    return true;
                } else {
                    // Not logged in 
                    return false;
                }
            } else {
                // Not logged in 
                return false;
            }
        } else {
            // Not logged in 
            return false;
        }
    } else {
        // Not logged in 
        return false;
    }
}

function esc_url($url) {

    if ('' == $url) {
        return $url;
    }

    $url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\\x80-\\xff]|i', '', $url);

    $strip = array('%0d', '%0a', '%0D', '%0A');
    $url = (string) $url;

    $count = 1;
    while ($count) {
        $url = str_replace($strip, '', $url, $count);
    }

    $url = str_replace(';//', '://', $url);

    $url = htmlentities($url);

    $url = str_replace('&amp;', '&#038;', $url);
    $url = str_replace("'", '&#039;', $url);

    if ($url[0] !== '/') {
        // We're only interested in relative links from $_SERVER['PHP_SELF']
        return '';
    } else {
        return $url;
    }
}

function filelog($data){
    $myfile = fopen("mylog.txt", "w");
    fwrite($myfile,$data+"\r\n");
    fclose($myfile);
    return;
}

我在代码中只看到3个
$\u SESSION[…]=
作业。如果你只分配了3个,你怎么能期望在$会话中得到6个项目呢?我想我解释得不够清楚,我提到我注意到,如果我不使用REGENATE_会话id,我会得到6$会话,使用它,生成3个,但我只需要1个,有数据的,而不是空的,每当我到达受保护的页面,如果凭据正确,isset(…)将失败,因为正在打开一个空的$\会话。简而言之,要么杀死剩余的2个空会话,最后保留我需要的一个真正的会话变量,要么找到打开正确会话的方法。你是说你有6个不同的会话cookie?在C:\xampp\tmp中,只有一个$_会话数组,这是存储会话的默认路径,无论我运行它,就像现在一样,至少创建了3个文件,名称像“sess_us35cio0c8mclaq49h9k9e7sd3”,基本上每次调用一个会话(其中2个为空,只有1个有正确的数据),1在索引页中创建,1在进程登录中创建,1在受保护页中创建。当它们被删除时,只有一个会话的id为(true);我在代码中只看到3个
$\u SESSION[…]=
作业。如果你只分配了3个,你怎么能期望在$会话中得到6个项目呢?我想我解释得不够清楚,我提到我注意到,如果我不使用REGENATE_会话id,我会得到6$会话,使用它,生成3个,但我只需要1个,有数据的,而不是空的,每当我到达受保护的页面,如果凭据正确,isset(…)将失败,因为正在打开一个空的$\会话。简而言之,要么杀死剩余的2个空会话,最后保留我需要的一个真正的会话变量,要么找到打开正确会话的方法。你是说你有6个不同的会话cookie?在C:\xampp\tmp中,只有一个$_会话数组,这是存储会话的默认路径,无论我运行它,就像现在一样,至少创建了3个文件,名称像“sess_us35cio0c8mclaq49h9k9e7sd3”,基本上每次调用一个会话(其中2个为空,只有1个有正确的数据),1在索引页中创建,1在进程登录中创建,1在受保护页中创建。当它们被删除时,只有一个会话的id为(true);
<?php
include_once 'psl-config.php';

function sec_session_start() {
    $session_name = 'sec_session_id';   // Set a custom session name
    $secure = true;
    // This stops JavaScript being able to access the session id.
    $httponly = true;
    // Forces sessions to only use cookies.
    if (ini_set('session.use_only_cookies', 1) === FALSE) {
        header("Location: ../error.php?err=Could not initiate a safe session (ini_set)");
        exit();
    }
    // Gets current cookies params.
    $cookieParams = session_get_cookie_params();
    session_set_cookie_params($cookieParams["lifetime"],
        $cookieParams["path"], 
        $cookieParams["domain"], 
        $secure,
        $httponly);
    // Sets the session name to the one set above.
    session_name($session_name);
    session_start();            // Start the PHP session 
    session_regenerate_id(true) // regenerated the session, delete the old one. 
}

function login($Usuario, $Contraseña, $mysqli) {


    // Using prepared statements means that SQL injection is not possible. 
    if ($stmt = $mysqli->prepare("SELECT RFC, Usuario, Contrasena 
        FROM empleado
       WHERE Usuario = ?
        LIMIT 1")) {
        $stmt->bind_param('s', $Usuario);  // Bind "$email" to parameter.
        $stmt->execute();    // Execute the prepared query.
        $stmt->store_result();

        // get variables from result.
        $stmt->bind_result($RFC, $username, $db_password);
        $stmt->fetch();

        if ($stmt->num_rows == 1) {
            // If the user exists we check if the account is locked
            // from too many login attempts 

            if (checkbrute($RFC, $mysqli) == true) {
                // Account is locked 
                // Send an email to user saying their account is locked
                return false;
            } else {
                // Check if the password in the database matches
                // the password the user submitted. We are using
                // the password_verify function to avoid timing attacks.                         
                if ($Contraseña==$db_password) {
                    // Password is correct!
                    // Get the user-agent string of the user.
                    $user_browser = $_SERVER['HTTP_USER_AGENT'];
                    // XSS protection as we might print this value
                    $RFC = preg_replace("/[^0-9]+/", "", $RFC);
                    $_SESSION['user_id'] = $RFC;
                    // XSS protection as we might print this value
                    $username = preg_replace("/[^a-zA-Z0-9_\-]+/", 
                                                                "", 
                                                                $username);
                    $_SESSION['username'] = $username;
                    $_SESSION['login_string'] = hash('sha512', 
                              $db_password . $user_browser);
                    // Login successful.
                    return true;
                } else {
                    // Password is not correct
                    // We record this attempt in the database
                    $now = time();
                    $mysqli->query("INSERT INTO registo_login(user_id, Tiempo)
                                    VALUES ('$RFC', '$now')");
                    return false;
                }
            }
        } else {
            // No user exists.
            return false;
        }
    }
}

function checkbrute($RFC, $mysqli) {
    // Get timestamp of current time 
    $now = time();

    // All login attempts are counted from the past 2 hours. 
    $valid_attempts = $now - (2 * 60 * 60);

    if ($stmt = $mysqli->prepare("SELECT Tiempo 
                             FROM registro_login 
                             WHERE RFC = ? 
                            AND Tiempo > '$valid_attempts'")) {
        $stmt->bind_param('i', $RFC);

        // Execute the prepared query. 
        $stmt->execute();
        $stmt->store_result();

        // If there have been more than 5 failed logins 
        if ($stmt->num_rows > 5) {
            return true;
        } else {
            return false;
        }
    }
}

function login_check($mysqli) {
    // Check if all session variables are set 
    if (isset($_SESSION['user_id'], 
                        $_SESSION['username'], 
                        $_SESSION['login_string'])) {
        filelog("yay");

        $RFC = $_SESSION['user_id'];
        $login_string = $_SESSION['login_string'];
        $username = $_SESSION['username'];

        // Get the user-agent string of the user.
        $user_browser = $_SERVER['HTTP_USER_AGENT'];

        if ($stmt = $mysqli->prepare("SELECT Contrasena 
                                      FROM empleados 
                                      WHERE RFC = ? LIMIT 1")) {
            // Bind "$RFC" to parameter. 
            $stmt->bind_param('i', $RFC);
            $stmt->execute();   // Execute the prepared query.
            $stmt->store_result();

            if ($stmt->num_rows == 1) {
                // If the user exists get variables from result.
                $stmt->bind_result($Contraseña);
                $stmt->fetch();
                $login_check = hash('sha512', $Contraseña . $user_browser);

                if (hash_equals($login_check, $login_string) ){
                    // Logged In!!!! 
                    return true;
                } else {
                    // Not logged in 
                    return false;
                }
            } else {
                // Not logged in 
                return false;
            }
        } else {
            // Not logged in 
            return false;
        }
    } else {
        // Not logged in 
        return false;
    }
}

function esc_url($url) {

    if ('' == $url) {
        return $url;
    }

    $url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\\x80-\\xff]|i', '', $url);

    $strip = array('%0d', '%0a', '%0D', '%0A');
    $url = (string) $url;

    $count = 1;
    while ($count) {
        $url = str_replace($strip, '', $url, $count);
    }

    $url = str_replace(';//', '://', $url);

    $url = htmlentities($url);

    $url = str_replace('&amp;', '&#038;', $url);
    $url = str_replace("'", '&#039;', $url);

    if ($url[0] !== '/') {
        // We're only interested in relative links from $_SERVER['PHP_SELF']
        return '';
    } else {
        return $url;
    }
}

function filelog($data){
    $myfile = fopen("mylog.txt", "w");
    fwrite($myfile,$data+"\r\n");
    fclose($myfile);
    return;
}