如何正确启动和销毁会话?

Posted

技术标签:

【中文标题】如何正确启动和销毁会话?【英文标题】:How to start and destroy session properly? 【发布时间】:2016-09-17 22:50:41 【问题描述】:

所以,我有:

index.php(登录和注册表、欢迎页面等) login.php(这是一个简单的登录验证php文件,当用户在index.php上按下提交时执行), home.php(用户正确登录后重定向的站点) logout.php(logout.php的反面,将用户重定向到index.php并销毁会话(我以为..)

问题是,即使在我正确登录之前,我也可以随时访问 home.php。 我将 start_session() 放在需要 $_SESSION 变量的每个页面上,并将 session_destroy() 也放在 logout.php 中。

所以这里是 php 文件的代码:

index.php

<body>

<?php
    require_once('config.php');
    if ($maintanance) 
        echo "Az oldal karbantartás alatt van.";
    
    else if ($db_conn_error) 
        echo "Something went wrong according to database connection.";
    
    else 
            include('reg.php');
            include('./templates/header.php');
?>

    <section>
        <form id="login_form" action="" method="POST">
            <h2>Already a member? Sign in!</h2>
            <p>Username: <input type="text" name="username"></p>
            <p>Password: <input type="password" name="password"></p>
            <input type="submit" name="login_submit" value="Sign In">
            <?php include 'login.php'; ?>
        </form>

        <form id="reg_form" action="" method="POST" onsubmit="return validation();">
            <h2>Sign up Now!</h2>
            <p>Username: <input type="text" name="username" placeholder="min. 5 characters">
            <span id="user_error"></span>
            </p>
            <p>Password: <input type="password" name="password" placeholder="min. 8 characters"></p>
            <p>Password again: <input type="password" name="password_again"></p>
            <p>E-mail: <input type="email" name="email" size="30"></p>
            <p>Date of birthday:
                <input type="number" name="bd_year" min="1950" max="2016">
                <input type="number" name="bd_month" min="1" max="12">
                <input type="number" name="bd_day" min="1" max="31">
            </p>
            <input type="submit" name="reg_submit" value="Sign Up">
        </form>
    </section>
</body>
</html>
<?php  ?>

login.php

<?php

    include 'config.php';

    if (isset($_POST["login_submit"]))
    

        $username = $_POST["username"];
        $password = $_POST["password"];

        $query = "SELECT username, hashed_password FROM users WHERE username = '$username';";

        $result = mysqli_query($conn, $query);
        $row = mysqli_fetch_assoc($result);
        $rows_num = mysqli_num_rows($result);

        $password_match_error_message = false;

        if ($rows_num == 0) 
            echo "<p class='login_error_msg'>This user doesn't exist!</p>";
        
        else 
            $password_match = password_verify($password, $row['hashed_password']);
            if (!$password_match) 
                echo "<p class='login_error_msg'>Wrong password!</p>";
            
            else 
                session_start();
                $_SESSION["user"] = $username;
                header("Location: home.php");
            
        
    

?>

home.php

<?php
    session_start();
    if (isset($_SESSION["user"])) 
?>

<!DOCTYPE html>

<html>

<head>
     <title>Spookie - Social Network</title>
     <link rel="stylesheet" type="text/css" href="./css/style.css">
</head>

<body>

    <?php
        include './templates/header.php';
    ?>

    <?php  else  echo "You are not logged in!";  ?>

</body>

</html>

logout.php

<?php
    session_unset($_SESSION["user"]);
    session_destroy();
    header("Location: index.php");
?>

我知道,通过代码很难看出真正发生了什么,登录有效,但会话不是。

问题:尽管我没有登录,但我输入并且 home.php 始终可以访问。logout.php 不会破坏会话,甚至会话无法启动。

非常感谢您的帮助! :)

【问题讨论】:

你的 home.php 需要在正文中进行过滤,而不是在文档类型之前,如果你想做你想做的事情(即生成一个页面但有过滤的内容)。也就是说:当您在没有会话的情况下访问该页面时,您实际上会得到什么,例如使用 cURL 或 wget?请更新您的帖子,提供出现问题的证据,以便我们在尝试回答此问题之前了解您所知道的。 【参考方案1】:

问题出在 logout.php 中。

您还应该声明session_start() 以确保您可以删除$_SESSION["user"] 变量。

可能还有其他问题,因为我看不到整个代码。如果我错了,请纠正我。

看看另一个解释设置会话变量的典型方法的答案

【讨论】:

天哪,非常感谢!是的,我将 session_start() 放到 logout.php 中,它终于可以工作了! :)【参考方案2】:

根据本手册:http://php.net/manual/en/function.session-destroy.php

为了完全终止会话,比如注销用户, 会话 ID 也必须取消设置。如果使用 cookie 来传播 会话 id(默认行为),则会话 cookie 必须是 删除。 setcookie() 可以用于此。

手动链接有一个关于如何做到这一点的完整工作示例。从那里偷来的:

<?php
// Initialize the session.
// If you are using session_name("something"), don't forget it now!
session_start();

// Unset all of the session variables.
$_SESSION = array();

// If it's desired to kill the session, also delete the session cookie.
// Note: This will destroy the session, and not just the session data!
if (ini_get("session.use_cookies")) 
    $params = session_get_cookie_params();
    setcookie(session_name(), '', time() - 42000,
        $params["path"], $params["domain"],
        $params["secure"], $params["httponly"]
    );


// Finally, destroy the session.
session_destroy();
?>

【讨论】:

【参考方案3】:

session_start() 将开始会话。

session_destroy() 将破坏会话。

要设置会话数据,您可以这样做。

`
    $_SESSION['is_logged_in'] = true;
`

用于检查是否存在会话或检查用户是否已登录

`
    If(isset($_SESSION['is_logged_in'] ) 
    else 
    //redirect to login page
     
 `

【讨论】:

以上是关于如何正确启动和销毁会话?的主要内容,如果未能解决你的问题,请参考以下文章

如何销毁 Symfony 2 中的所有会话

如何一键销毁php会话

Chrome 和 Internet Explorer 中的 Codeigniter 销毁会话

如何清空/销毁 Rails 中的会话?

如何彻底销毁护照/快递会话?

如何创建将在 Symfony2 中过期/销毁会话的命令控制台?