簡體   English   中英

刷新后登錄會話被破壞

[英]login session destroyed after refresh

我已經在Google的一些幫助下完成了登錄腳本,但問題是每次我刷新頁面時,它都會注銷並重定向到登錄頁面。 因此,基本上,我希望用戶輸入詳細信息后登錄,並且一次刷新后不注銷。 我的代碼是:

<?php

if(!isset($_SESSION)){
session_start();
}

$username = mysqli_real_escape_string($con, $_POST['username']);
$password = mysqli_real_escape_string($con, $_POST['password']);

if ($username && $password)

{


$result = mysqli_query($con, "SELECT * FROM admin WHERE username='$username' ");

$numrows = mysqli_num_rows($result);

if($numrows !=0)
{
    while($row = mysqli_fetch_assoc($result))
    {
        $dbusername = $row["username"];
        $dbpassword = $row["password"]; 

    }
        if($username==$dbusername && $password==$dbpassword)
        {

            $_SESSION['username'] = $dbusername;
        }
        else
            echo "Incorrect Password";
}       
else
    header("location: login.php"); 


}
else    
header("location: login.php"); 
?>

mysqli_real_escape_string() 要求您必須將數據庫的主動/建立的連接。 由於在連接之前正在執行m_r_e_s()調用,因此只需返回布爾FALSE即可表示失敗。 因此,您浪費了“引用”值。

插入字符串中的布爾假值只會轉換為空字符串,因此查詢看起來像

SELECT ... WHERE username=''
                           ^---see the boolean false in there?

您的代碼序列應為:

session_start();
connect_to_db();
prepare_variables();
do_query();

而且由於您使用的是mysqli,為什么仍要手動轉義變量? 您可以只使用准備好的語句+占位符,然后完全繞開該問題。

學習要點1:會議

這里有一些與會議有關的學習要點,以及如何有效地使用它們。 請注意,您代碼的問題是您在詢問是否在調用會話開始之前設置了會話,因此超全局$ _SESSION不可用,因此您的邏輯語句始終返回false,除非您在登錄時調用會話開始時無論如何都不要調用會話開始。 在配置文件中調用會話開始1次(請確保在所有“視圖/頁面”中都包含此文件,然后您可以檢查會話是否設置為正常。請仔細閱讀此代碼並嘗試了解其所做的一切這樣您就可以利用php會話提供的功能。

添加到login.php

//upon successful validation of login.
//create an object to store basic user information in. 

$user = (object) ['username'=>$username,'hash_password'=>$password,'group'=>$usergroup,'site_secret'=>$secret];//your user object

$_SESSION['user'] = $user;//store the object in the users session.

添加到您的config.php或所有頁面中包含的任何文件

GLOBAL const static $secret = (string)'someUltraSecretStringThatIsDifficultToGuess';//your site wide secret.(you should probably add this to your config file instead of the login.
session_start(); 

//you have to call session start or you don't have access to $_SESSION superglobal, 
//regardless of a user being logged in or logged out they have a session.
//as a programmer it is your job to figure out how to store data in the session

if(isset($_SESSION['user']) && is_object($_SESSION['user']) && $_SESSION['user']->site_secret == $secret)
{
    $loggedInUser = $_SESSION['user'];//if an authenticaed user session is set and is an object and contains our site secret, we assign the $loggedInUser variable to it. so we can call this variable instead of calling the session ad nauseum in our code.
}

現在在文件中以測試用戶是否已登錄

if($loggedInUser !== null && is_object($loggedInUser) && $loggedInUser->site_secret = $secret)
{
    //user is logged in. no reason to even call the database at this point, unless there is extra information you need.
    //if said information is going to be accessed on multiple pages, its probably wise to include it in the object when you create it during the login process. don't store overly sensitive
    //information in the object in any circumstance. things like credit card numbers, plain text passwords, security questions are big no nos.
}

現在,如果您需要從函數內部調用此對象,則有兩種方法

//pass by reference

function foo($loggedInUser) 
{
    //your object is available here because you passed by reference! 
    //you can check if a user is loggedIn from within functions now without a single call to the database!
}

//pass with global language feature.
function bar()
{
    global $loggedInUser; //object is available here through usage of global directive. nifty eh?
}

其他考慮

考慮將站點范圍的機密屬性添加到您的loggingInUser對象中,並檢查此機密是否存在以標識有效會話。 如果未通過傳遞格式錯誤的get請求來登錄用戶,則可以創建一個名為$ loggedInUser的變量。 很有可能攻擊者無法猜測您的站點秘密。 在第一個示例中顯示了此站點范圍秘密的示例。

學習要點#2:面向對象的Mysqli速成班

創建連接對象。

$mysqli = new mysqli("db-host","db-username","db-password","db-name");

設置字符集

//since your object is already created, you can now set a property on the object

$mysqli->set_charset("utf8");//set it to whatever the collation of your database is.

//side note: you should user utf_unicode_ci in your database and utf8 in php.

運行查詢

$query = $mysqli->query("SELECT column1,column2,column3 FROM table1 WHERE 1 LIMIT 30");

//getting number of rows
$num_rows = $query->num_rows;//your mysqli object has morphed into $query at this point.

//working with the result set
if($num_rows > 0)
{
    while($row = $query->fetch_assoc())
    {
    echo '<li>'.$row["column1"].' | '.$row["column2"].' | '.$row["column3"].'</li>';
    }
    $query->close();//optionally close the query object NOTE: the $mysqli object is still open
    $query->free();//optionally free the result set
}
//when you are done with your $mysqli object close the connection
$mysqli->close();

准備好的語句:手動轉義值的替代方法

$stmt = $mysqli->prepare("SELECT column1,column2,column3 FROM table1 WHERE column4 = ? column5 = ? and column6 = ?");//prepare our query.

//now we need to assign our variables to the question marks in the statement above in the correct order.
// s represents string, d represents double and i represents an integer.
$stmt->bind_param('sdi',$column4,$column5,$column6);//for illustrative purposes i name the variables the same as the column they correspond to so you can understand.

//now that we have bound our parameters to our statement wehave to execute it. if it doens't execute there is an error in our query or binding parameters

if($stmt->execute())
{
    //now we have two ways we can work with this result set. i am only going to show you what i consider the best way, `bind_result().
    $stmt->bind_result($column1,$column2,$column3);//binds in the same order of our columns.
    if($stmt->num_rows > 0) {
        //great, our query returned a result! lets work with this data now
        while($stmt->fetch())
        {
            echo '<li>'.$column1.' | '.$column2.' | '.$column3.'</li>';//we prent each row of our result. easy peasy
        }
        $stmt->close();//no need to free the result, as it is not stored by default.
    }
    //if there were no results, no need to close stmt as it was automatically closed by default.    
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM