【问题标题】:Simple Logout Script简单的注销脚本
【发布时间】:2014-04-29 12:44:33
【问题描述】:

我正在使用下面的代码让用户登录。创建新会话后,他们将被重定向到一个新页面 - content.php。我想知道销毁会话并注销用户并将他们重定向回index.php 的最佳方式/正确方式是什么。

<?php 
if (isset($_REQUEST['signin'])){

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

$query = "SELECT * FROM `user` WHERE username='$username' and password='$password'";
$result = mysql_query($query) or die(mysql_error());
$count = mysql_num_rows($result);

if ($count == 1){
$_SESSION['username'] = $username;
header('Location: content.php');
}
else{
echo "Invalid Login Credentials.";
}
}
if (isset($_SESSION['username'])){
$username = $_SESSION['username'];
header('Location: content.php');
}
?>


<form method="post" name="login">
        <?php 
        if (isset($msg) & !empty($msg)) {
                    echo $msg;
                    }
        ?>
        <label for="username">Username:</label><br>
        <input type="text" name="username"><br>
        <label for="password">Password:</label><br>
        <input type="password" name="password"><br>
        <button type="submit" name="signin">Sign in</button>
</form>

我知道这个脚本有缺陷(例如,未加密的密码),但现在我正在寻找一个简单的脚本来注销。

【问题讨论】:

  • 它似乎是今天的主题,但使用mysql_* 已被弃用,很快将被删除。请开始使用PDO。 PS你也容易感染SQL Injects
  • 或者使用 MySQLi。我个人更喜欢 MySQLi,但 PDO 也是一种选择。

标签: php html database


【解决方案1】:

注销用户的最佳和最简单的方法是销毁整个会话或取消设置必要的会话密钥。

session_destroy();
// or...
unset($_SESSION['username'];

header('Location: index.php');

我更喜欢未设置,因为您可能希望在会话数组中存储更多数据。

【讨论】:

  • 我应该有一个单独的文件吗?类似 logout.php 的东西?
  • 那是你自己的选择。请记住在调用会话函数之前始终通过 session_start() 启动会话。
  • 我已经包含了一个单独的 connection.php 文件,其中我有 session_start();放在那里可以吗?
  • 在另一个 php 文件中包含 session_start() 就可以了,只要您在需要访问 php 变量的每个文件中都包含该 php 文件,或者在您不需要的 php 文件中调用 session_start包括“connection.php”到。
  • 你应该经常问自己,我需要这个变量吗?说再见用户名...是的,添加它。不,不要。
【解决方案2】:

首先你需要清理你的输入,所以

$username = mysql_real_escape_string($_POST['username']);
$password = mysql_real_escape_string($_POST['password']);

现在,关于清除会话。你的注销脚本应该使用unset

unset($_SESSION['username']);
unset($_SESSION['password']);

【讨论】:

  • 永远不要在会话中存储密码。
  • @JordiKroon 并且不要保留密码,加密它。即使你必须使用md5()
  • @13ruce1337 在 99.9% 的情况下,您不需要在会话中存储密码。
  • @JordiKroon 我同意你的看法,只是添加如果你必须保留密码,无论是$_SESSION 还是SQL,你都想加密它。
【解决方案3】:
session_start();
$_SESSION = array();
if (ini_get("session.use_cookies")) {
    $params = session_get_cookie_params();
        setcookie(session_name(), '', time() - 42000,
        $params["path"], $params["domain"],
        $params["secure"], $params["httponly"]
    );
}
session_destroy();
header("Location: index.php"); exit;

【讨论】:

  • 这个答案与 PHP 文档us2.php.net/manual/en/function.session-destroy.php 中的答案基本相同。
  • 但是如果重定向后有代码,不应该加一个return;吗?
  • @developerwjk 不,你想要exit()
  • 我明白你的意思,但我认为exit 更合适。
  • 我在想return; 我猜是因为这是你在重定向后将在 Java/JSP 中使用的。
【解决方案4】:

首先,查询前请检查你的查询变量,否则有SQL注入的风险。

接下来,当您设置会话时,您必须在脚本顶部调用 session_start(); 以使用会话。

最后,要注销用户,只需调用session_destroy(); 即可销毁现有会话。

我已经稍微改写了你的代码

<?php 
session_start();
if (isset($_REQUEST['signin'])){
    $username = $_POST['username'];
    $password = $_POST['password'];

    $sql_connection = new mysqli("dbHost", "dbUsername", "dbPassword", "dbName");
    if($sql_connection->connect_errno){
        die("db error");
    }
    $username = $sql_connection->real_escape_string($username);
    $password = $sql_connection->real_escape_string($password);
    $query = "SELECT * FROM `user` WHERE username='$username' and password='$password' LIMIT 1;";
    $result = $sql_connection->query($query) or die("db error");
    $count = $result->num_rows;

    if ($count == 1){
        $_SESSION['username'] = $username;
        header('Location: content.php');
        die();
    }else{
        echo "Invalid Login Credentials.";
    }
}elseif(isset($_SESSION['username'])){
    $username = $_SESSION['username'];
    header('Location: content.php');
    die();
}
?>
<form method="post" name="login">
        <?php 
        if (isset($msg) & !empty($msg)) {
                    echo $msg;
                    }
        ?>
        <label for="username">Username:</label><br>
        <input type="text" name="username"><br>
        <label for="password">Password:</label><br>
        <input type="password" name="password"><br>
        <button type="submit" name="signin">Sign in</button>
</form>

由于即将删除,因此使用 MySQLi 而不是 MySQL。它还转义输入并设置会话。

【讨论】:

    【解决方案5】:
    <?php
    if (!isset($_SESSION)) { session_start(); }
    
    $_SESSION = array(); 
    
    session_destroy(); 
    
    header("Location: login"); //login.php if you havent setup your htaccess to use without.php
    exit();
    ?>
    

    【讨论】:

    • 感谢您的贡献。仅代码答案被标记为低质量;未来的访问者肯定会很高兴简要说明其工作原理以及为什么它是解决问题的好方法。
    猜你喜欢
    • 2016-12-06
    • 2014-02-14
    • 2016-07-17
    • 2011-04-14
    • 2015-03-17
    • 1970-01-01
    • 2017-05-22
    • 2013-05-11
    • 2011-08-29
    相关资源
    最近更新 更多