dongshi1102 2013-02-05 21:28
浏览 120
已采纳

首次尝试登录时未识别会话

Issue resolved - see: https://stackoverflow.com/a/14719452/1174295

--

I've come across a problem within (at least) Google Chrome and Safari.

Upon the first attempt at logging in, the user is not redirected. The session is created, but it is almost as if it is not detected, and takes the user back to the index page. Upon a second attempt, the correct redirect is issued and the user is taken to the correct page.

The script works fine in Firefox, and I have checked extensively to see if the correct data is being returned, which it is. I've searched and I've searched and I've searched, but unfortunately nothing of use has cropped up.

Access.php - User logging in

<?php
session_start();
ob_start();


include_once('db.class.php');
include_once('register.class.php');
include_once('login.class.php');


$db = null;
$reg = null;
$log = null;


$db = new Database();
$log = new Login($db, null, null, null, null, null, null);


if (isset($_SESSION['login'])) {    
    $log->redirectUser($_SESSION['login']);
}


include_once('includes/header.html');

?>

Some HTML...

<?php
    if (isset($_POST['logsub'])) {
        $db = new Database();
        $log = new Login($db, $_POST['email'], $_POST['pass']);

        $validation = &$log->validate();

        if(empty($validation)) {
            $log->redirectUser($_SESSION['login']);
        } else {
            echo "<div id='error'><div class='box-error'><p style='font-weight: bold'>The following errors occured...</p><ul>";

                for ($i = 0; $i < count($validation); $i++) {
                    echo "<li>" . $log->getErrorMessage($validation[$i]) . "</li>";
                }
            echo "</ul></div></div>";
        }
    }
?>

Login.class.php - Login class

// Validate the credentials given
public function validateLogin() {
    // Hash the plain text password
    $this->hashedPass = $this->hashPassword();

    try {
        $query = $this->dbcon->prepare("SELECT Login_ID, Login_Email, Login_Password FROM Login WHERE Login_Email = :email AND Login_Password = :pass");
        $query->bindParam(':email', $this->email, PDO::PARAM_STR);
        $query->bindParam(':pass', $this->hashedPass, PDO::PARAM_STR);
        $query->execute();

        $fetch = $query->fetch(PDO::FETCH_NUM);
        $this->loginid = $fetch[0];

        // If a match is found, create a session storing the login_id for the user
        if ($query->rowCount() == 1) {
            $_SESSION['login'] = $this->loginid;    
            session_write_close();
        } else {
            return LOG_ERR_NO_MATCH;
        }
    } catch (PDOException $e) {
        $this->dbcon->rollback();
        echo "Error: " . $e->getMessage();
    }
}

// Fetch the customer ID
private function getCustId() {
    try {
        $query = $this->dbcon->prepare("SELECT Customer.Cust_ID FROM Customer JOIN Login ON Customer.Login_ID = Login.Login_ID WHERE Customer.Login_ID = :loginid");
        $query->bindParam(':loginid', $this->loginid, PDO::PARAM_INT);
        $query->execute();

        $fetch = $query->fetch(PDO::FETCH_NUM);     
        return $fetch[0];
    } catch (PDOException $e) {
        $this->dbcon->rollback();
        echo "Error: " . $e->getMessage();
    }
}

// Check the registration progress - are they verified? paid?
// This function is used elsewhere hence the $sessionid argument
public function checkRegistration($sessionid) { 
    $this->loginid = $sessionid;
    $this->custid = $this->getCustId();

    try {
        $queryVer = $this->dbcon->prepare("SELECT Cust_ID FROM Customer_Verify_Email WHERE Cust_ID = :custid");
        $queryVer->bindParam(":custid", $this->custid, PDO::PARAM_INT);
        $queryVer->execute();

        $queryFee = $this->dbcon->prepare("SELECT Cust_ID FROM Initial_Fee_Payment WHERE Cust_ID = :custid");
        $queryFee->bindParam(":custid", $this->custid, PDO::PARAM_INT);
        $queryFee->execute();

        // If a record exists in the verify table, return the value 1. This means the user has not yet verified their email.
        if ($queryVer->rowCount() == 1) {
            return 1;
        } else {
            // If a record does not exist in the payment table, no payment has been made. Return 2.
            if ($queryFee->rowCount() == 0) {
                return 2;
            // Otherwise, email is verified and the payment has been made.
            } else {
                return 0;
            }
        }

    } catch (PDOException $e) {
        $this->dbcon->rollback();
        echo "Error: " . $e->getMessage();
    }
}

// Redirect the user accordingly
public function redirectUser($sessionid) {
    $this->loginid = $sessionid;    
    $logNum = $this->checkRegistration($this->loginid);

    if ($logNum == 0) {
        header("Location: fbedder/details.php", true, 200);
        exit();
    } else if ($logNum == 1) {
        header("Location: fbedder/verification.php", true, 200);
        exit();
    } else if ($logNum == 2) {
        header("Location: fbedder/payment.php", true, 200);
        exit();
    }
}

Here's a link to the site: fbedder/ -> I have set-up a test account with the credentials -> email: test@ / password: test123321

To reiterate, the problem exists only in Google Chrome and Safari (the Safari being on my iPhone) and lies purely within the logging in aspect. On the first attempt, the session will be ignored (it is created), and on the second attempt, the user will be redirected.

Any ideas? I've tried a multitude of possibilities...

-- Edit --

I know where the issue lies now.

When the redirect is called, it sends the user to the details.php page. However, this page contains the following snippet of code:

if (!isset($_SESSION['login'])) {
    header("Location: fbedder/index.php");
}

Obviously what is happening, is that the session is not being detected / saved / "whatevered", and as a result is sending the user back to the index page. Is there are a way to ensure the $_SESSION is not effectively lost. I had read about this before posting here, and is why I inserted session_write_close(), but that doesn't seem to be doing the desired effect.

  • 写回答

1条回答 默认 最新

  • duanhuancong1969 2013-02-06 00:20
    关注

    After diagnosing the problem being within the fact the $_SESSION variable was effectively being lost, I read up about the session_write_close() function and came across this comment:

    My sessions were screwing up because I had 2 different session IDs going at once:

    • 1 PHPSESSID cookie for domain.com
    • 1 PHPSESSID cookie for www.domain.com

    This fixed it:

    //At the beginning of each page...

    session_set_cookie_params (1800,"/","domain.com"); session_start();

    Source: http://pt2.php.net/manual/en/function.session-write-close.php#84925

    Setting the parameters resolved the issue.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥200 uniapp长期运行卡死问题解决
  • ¥15 latex怎么处理论文引理引用参考文献
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?