如何改进此登录/会话代码


How can I improve on this login/session code?

我一直在学习如何创建一个带有会话的登录系统,以便在创建会话之前无法访问页面。目前它非常简单,不安全。

问题:我如何改进此代码(如下所示)以使会话更加安全?如果你知道我可以遵循的关于登录安全会话的教程,请发布链接!谢谢

代码:

checkLogin.php:

<!--Include Database connections info-->
<?php include('config.php'); ?>
<?php
    // username and password sent from form 
    $myusername=$_POST['myusername'];   
    $mypassword=$_POST['mypassword']; 
    // To protect MySQL injection (more detail about MySQL injection)
    $myusername = stripslashes($myusername);
    $mypassword = stripslashes($mypassword);
    $myusername = mysql_real_escape_string($myusername);
    $mypassword = mysql_real_escape_string($mypassword);
    $sql="SELECT username, password FROM users WHERE username='$myusername' and password='$mypassword'";
    $result=mysql_query($sql);
    // Mysql_num_row is counting table row
    $count=mysql_num_rows($result);
    // If result matched $myusername and $mypassword, table row must be 1 row
    if($count==1) {
        session_start();
        session_register("myusername");
        session_register("mypassword"); 
        header("location:login_success.php?");
        exit;
    }
    else {
        echo "Wrong Username or Password";
    }
?>

login_success.php:

<?php
    session_start();
    if(!isset($_SESSION['userid'])) {
        header("location:main_login.html");
        exit;
    }
    if(isset($_SESSION['userid'])) {
        header("location:index.php");
        exit;
    }   
?>
<?php
    $myusername=$_POST['myusername'];   
    $mypassword=$_POST['mypassword']; 
    $mysqli = new mysqli("localhost", "root", "password", "DataBase");
    // Check Connection
    if (!mysqli_connect_errno()) 
    {
        printf("Connect failed");
        exit();
    }
    // Move to MySQL(i) as MySQL is now obslete and use Prepare statment for protecting against SQL Injection in better and easier way
    $stmt = $mysqli->prepare('SELECT username FROM users WHERE username= ? and password= ?');
    $stmt->bind_param("ss", $myusername, $mypassword);
    //ss means expecting a variable of type string
    $stmt->execute();
    $count=mysqli_stmt::$num_rows($stmt);
    if($count>0) 
    {
        session_start();
        //Session Register is now history better go with
        $_SESSION['userid'] = $myusername;
        $_SESSION['mypassword'] = $mypassword;
        header("location:index.php");
    }
    else 
    {
        echo "Wrong Username or Password";
    }
?>

而不是重定向到login_success.php,只重定向到index.php

session_start();
if(!isset($_SESSION['userid'])) {
    header("location:main_login.html");
    exit;
}  

看起来session_register已被弃用,建议通过php.net注册会话变量。已弃用的信息:

$_SESSION["session_var_name"] = "value";

我认为在会话中存储实际的密码值是不好的。我想不出这样做有什么好处。

您所需要做的就是在会话中存储用户已成功通过身份验证的内容。

以下是您可以在session_start()下面使用的代码示例

$_SESSION['logged_in_user'] = $myusername;
$_SESSION['logged_in_user_session'] = session_id();

下面是可以用来检查用户是否在整个应用程序中通过身份验证的示例逻辑。

session_start();
// verify login
if (isset($_SESSION['logged_in_user']) && isset($_SESSION['logged_in_user_session'])) {
    if ($_SESSION['logged_in_user_session'] != session_id()) {
        // error: login
        header("Location: error_or_login_page.php");
        exit();
    }
}