PHP会话变量意外清除,尽管明显匹配,db值检查为空

时间:2013-04-29 12:01:21

标签: php variables pdo session-variables return-value

我一直在为这个问题苦苦挣扎数小时而且无法弄清楚我错过了什么。

我正在尝试构建一个无cookie的登录表单,如果攻击者能够修改它们,会话变量中也没有会损害应用程序的信息。

我的所有网页都包含以下代码。

我有两个问题:

  1. 每当我点击另一个页面时,它的作用就像$ _SESSION ['token']一样空,然后进入登录页面就好像是第一次访问一样。

  2. 它返回$ tokenid和$ tokentype为空,但每次加载页面时我都会调用它们(目的是避免将它们放入会话变量中)。

  3. 这是我目前的代码:

    <?php
    
    define('TIMEOUTMIN', 15);
    
    define('LOCKOUTMIN', 10);
    
    define('LOCKOUTNUM', 3);
    
    include("includes/pp/pbkdf2.php"); // this is basically calling the validate_password function
    
    include ("includes/vars/vars_dbconn.php"); // this contains the db data and $pdo
    
    $userid = $_POST['userid'];
    $userpw = $_POST['password'];
    
    $deltoq = "UPDATE LoginUser SET token = ?, online = ? WHERE online < ?";
    $prepdeltoq = $pdo->prepare($deltoq);
    $prepdeltoq->execute(array(NULL,NULL,time()));
    
    $loginq = "SELECT * FROM LoginUser WHERE ID = ?";
    $preplq = $pdo->prepare($loginq);
    $preplq->execute(array($userid));
    $getuser = $preplq->fetch(PDO::FETCH_ASSOC);
    $dbid = $getuser['ID'];
    $dbpass = $getuser['hash'];
    $dbbp = $getuser['bp'];
    $dbltime = $getuser['ltimeout'];
    
    $logintoq = "SELECT * FROM LoginUser WHERE token = ?";
    $prepltq = $pdo->prepare($logintoq);        
    $prepltq->execute(array($_SESSION['token']));
    $getoken = $prepltq->fetch(PDO::FETCH_ASSOC);
    $tokenid = $getoken['ID'];
    $tokentype = $getoken['type'];
    $totoken = $getoken['token'];
    
    $prolonglock = $pdo->prepare("UPDATE LoginUser SET ltimeout = ? WHERE ID = ?");
    $addbp = $pdo->prepare("UPDATE LoginUser SET bp = ? WHERE ID = ?");
    $loginwhen = $pdo->prepare("UPDATE LoginUser SET lastlogin = ? WHERE ID = ?");
    $loginlogq = $pdo->prepare("INSERT INTO LoginUserLog (ID, action)       
        VALUES(:ID, :action)");
    
    $logintokenid = $pdo->prepare("UPDATE LoginUser SET token = ? WHERE ID = ?");
    $loginonid = $pdo->prepare("UPDATE LoginUser SET online = ? WHERE ID = ?");
    $loginontok = $pdo->prepare("UPDATE LoginUser SET online = ? WHERE token = ?");
    
    if(!function_exists('LoginUser')) {
    
        function LoginUser($pwmessage) {
    
            if (session_name() <> 'MyWebApp') session_name('WesoftskyLogin');
            if (!session_id()) session_start();
    
            $_SESSION['token'] = '';
    
            include ("includes/header.php"); ?>
            <meta name="description" content="Login - MyWebApp"/>
            <title>Login - MyWebApp</title>
            <script type="text/javascript">
                event.keyCode == '';
                    function enterTab() {
                        if (event.keyCode == 13) {
                        var passInput = document.getElementById("password");
                        passInput.focus();
                        }
                    }
            </script>
        </head>
        <body onkeyup="enterTab()">
          <div id="homewrap">
            <div id="hometitle">MyWebApp</div>
          </div>
          <div id="id_formwrap">
            <form action="<?php echo htmlspecialchars($_SERVER['REQUEST_URI'].$_SERVER['QUERY_STRING']); ?>" method="post">
                <?php if (empty($pwmessage)) echo '<div>Please enter your login details</div>'; else echo '<div style="color:red">'.$pwmessage.'</div>'; ?><br />
                Login ID<br />
                <input type="text" name="userid" id="id" onKeyPress="return noenter(event)" /><br /><br />            
                <script>document.getElementById("id").focus()</script>
                Password<br />
                <input type="password" name="password" id="password" /><br /><br />
                <input type="submit" name="login" id="Submit" value="Login" />
            </form>
          </div>
        </body>
        </html>
    
        <?php exit();
        }
    }
    
    if(!function_exists('ProlongTime')) {
        function ProlongTime() {
            global $userid; 
            global $logintokenid;
            global $loginonid;
            global $loginontok;
            $timeoutodb = (time () + TIMEOUTMIN*60);
            if (!empty($userid)) {
                $_SESSION['token'] = bin2hex(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM));
                $logintokenid->execute(array($_SESSION['token'], $userid));
                $loginonid->execute(array($timeoutodb, $userid));
            } else {
                $loginontok->execute(array($timeoutodb, $_SESSION['token']));
            }
        }
    }
    
    if ($dbltime > time()) {
        $lockcheck = time() + LOCKOUTMIN*60;
        $prolonglock->execute(array($lockcheck,$userid));
        LoginUser('Your account is currently locked');
    }
    
    if(isset($_POST['logout'])) {
        $action = "Logged OUT";
        $loginlogq->execute(array(':ID' => $tokenid, ':action' => $action));
        LoginUser('Logged out');
    }
    
    if (isset($_POST['login'])) {   
        if ($dbid AND validate_password($userpw, $dbpass)) {  // Good login info
            //session_regenerate_id(true);      
            $action = "Logged IN";
            $loginlogq->execute(array(':ID' => $userid, ':action' => $action));
            $loginwhen->execute(array(time(), $userid));
            $addbp->execute(array(NULL, $userid));
            ProlongTime();
        } else { // Bad login info
            if ($dbbp >= LOCKOUTNUM-1) {
                $lockbp = time() + LOCKOUTMIN*60;
                $prolonglock->execute(array($lockbp,$userid));
                $action = "Locked (wrong password)";
                $loginlogq->execute(array(':ID' => $userid, ':action' => $action));
                LoginUser('Your account has been locked');
            }
            $addbp->execute(array($dbbp+1, $userid));
            $action = "Failed login";
            $loginlogq->execute(array(':ID' => $userid, ':action' => $action));
            LoginUser('Username or password is incorrect');
        }
    } elseif (empty($_SESSION['token'])) { // Loading the page first time (new session)
        LoginUser('');
    } elseif ($_SESSION['token'] <> $totoken) { // Session timeout
        $action = "Logged OUT (expired)";
        $loginlogq->execute(array(':ID' => $tokenid, ':action' => $action));
        echo 'tokenid: '.$tokenid;
    } else ProlongTime(); // While using the app and still within time
    
    
    $pdo = null;
    
    ?>
    

1 个答案:

答案 0 :(得分:1)

你需要把

session_start()

在页面的开头。