如何只允许一个用户在php中编辑表单?

时间:2020-04-24 00:55:15

标签: php sql forms

我有一个如下所示的php代码,其中通过数据库验证了用户名/密码,并且仅允许一个用户登录(在下面ph​​p代码的X行)

在php代码中,表 trace_users 用户名打开写入是列)保留登录用户的轨迹。当任何用户登录后,写入列上的打开列将设置为true,值为 1 。如果用户注销,则在写入列上将打开列设置为false,将其值设置为 0

已登录用户 => open = true, write = 1
用户注销时 => open = false, write = 0

php代码:

if ($user_from_db && password_verify($password, $user_from_db->user_pass)) {

    $sql = "SELECT * FROM trace_users where open='true'";
    if($result1 = mysqli_query($connect, $sql)){
        if(mysqli_num_rows($result1) > 0){   // Line X
            while($row = mysqli_fetch_array($result1)){
                if($row['open'] == "true") {
                        if(!isset($_SESSION['admin'])) {
                            $message = "user " . $row['user_name'] . " is currently editing the form. Want to take over ?";
                            echo "<script type='text/javascript'>if(confirm('$message')) {   } else {  };</script>";   // Line A                        
                            }
                    break;
                }
            }
        } else{
            $_SESSION['admin'] = true;
            $_SESSION['user_name'] = $username;
            $open="true";
            $write="1";
            $stmt= $connect->prepare("UPDATE trace_users SET open=?, write=? WHERE user_name=?");
            $stmt->bind_param('sss', $open, $write, $_SESSION['user_name']);
            $stmt->execute();
        }
    }

} else {
    echo "Invalid Username or Password";
}

在A行中,如果 userA 已登录,而另一个用户说 userB 尝试登录,则它将显示userA is currently editing the form. Want to take over ?

我要实现的是如果 userB 接管了在警报框中单击“确定” 的形式,那么 userA 应该进入只读模式(撤消)写访问权限)和 userB 被授予完全访问权限(写)。

userA => open = true, write = 0
userB => open = true, write = 1

这是我尝试过的:

在A行之后,我正在考虑添加这些行,以便尝试接管的用户能够登录。

$_SESSION['admin'] = true;
$_SESSION['user_name'] = $username;
$open="true";
$write="1";
$stmt= $connect->prepare("UPDATE trace_users SET open=?, write=? WHERE user_name=?");
$stmt->bind_param('sss', $open, $write, $_SESSION['user_name']);
$stmt->execute();

问题陈述:

我想知道我应该在上面的php代码中进行哪些更改,以便如果 userA 登录并且 userB也希望登录并尝试接管表单 那么 userA 应该没有写访问权限,而 userB 应该具有完全访问权限,即

userA (open=true , write=0)

userB (open=true, write=1)

注意:对于没有写访问权限的用户,将不会显示保存按钮。

4 个答案:

答案 0 :(得分:0)

我发现您的方法存在两个基本问题:

  • 可能会无意中将多个用户的trace_users.write列设置为1,除非您在更新表之前非常小心地锁定了表。这不是跟踪谁是“活动”编辑器的好方法。

  • 您的line "A"可能会显示一些HTML,但是直到用户确认是/否,它才会被执行。该步骤必须在其他地方完成。

一种更好的方法是让一条规范记录(可能在另一个表中)跟踪当前管理员,并且您的代码可以根据需要随时检查(或更新)该记录。每当用户选择进行更改时,PHP都会首先检查他们是否是活动的编辑器,如果是,则提交更新,否则拒​​绝更新。

您需要的一些服务器端功能的伪代码:

// When an update is requested:
if ( user is logged in and is the current admin ) {
    commit the change;
} else {
    Display "sorry" message to user
}

// -----------

// When user "X" logs in:
if ( another user is currently the active admin ) {
    Display message: "User Y is currently the admin. Take over?"
} else {
    Log in user "X" and set user "X" to current admin
}

// -----------

// When user "X" asks to take over as admin:
log in user "X"
set user "X" to current admin

我在这里看到的唯一缺陷是用户“ A”已登录并编辑并保存更改,用户“ B”可能在其浏览器中加载了旧数据。但这不是您要解决的问题,因此无论如何对您来说都不是问题。

答案 1 :(得分:0)

这样的事情怎么样?

$username = $_SESSION['user_name'];
$open="true";
$write="1";
$stmt=$connect->prepare("UPDATE trace_users SET write=0 WHERE write=1"); // revoke write access of all users
$stmt=$connect->prepare("UPDATE trace_users SET open=:open, write=:write WHERE user_name=:username");
$stmt->bind_param('sss', $open, $write, $username);
$stmt->execute();

这将撤消所有用户的写访问权限,然后仅为最近的用户设置写访问权限以请求写访问权限。

并且您将需要确保客户端有关其写访问权的撤销的最新信息,以便在必要时可以隐藏保存按钮。

答案 2 :(得分:0)

不建议在大型数据集上使用,但您可以使用一行选项来替换为包含对用户名的引用的更新:

model.fit()

这将针对表中的每个记录:

  • 将open保留为1,此处为1
  • 设置open = 1,其中用户名是targetUser
  • 让open = 0等于0,用户名不是targetUser
  • 设置write = 1,其中用户名是targetUser
  • 设置write = 0,其中用户名不是targetUser

一键通。


对于大型数据集,创建一个单独的表进行跟踪。您还可以使用其他智能功能,使用唯一键或主键来确保仅更新一条记录,然后验证“如果记录已更新(即$stmt= $connect->prepare("UPDATE trace_users SET open=IF(open=1 OR user_name=?,1,0), write=IF(user_name=?,1,0)"); $stmt->bind_param('sss', $_SESSION['user_name'], $_SESSION['user_name']); ),那么我会得到该标志,如果没有,那么其他人会得到它”。仅当您更习惯MySQL时才考虑。


警告:“打开”和“写入”都是关键字/保留字,您的SQL可能无法移植。换行或在开头加上诸如userOpen,userWrite之类的内容。我在下面的示例中添加了滴答声。在此处阅读更多信息:https://dev.mysql.com/doc/refman/8.0/en/keywords.html

rowCount() > 0

答案 3 :(得分:0)

问题更多的是流程逻辑,而不是代码:

  1. UserA连接(电话1,php授予访问权限:打开=> 1,写入=> 1)
  2. UserB连接(呼叫2,php显示弹出到UserB的窗口:open => 1)
  3. UserB必须决定接管(或不接管)(电话3,php授予对UserB的写访问权,并撤消UserA的写访问权:UserA写=> 0,UserB写=> 1)

使用代码管理第1步和第2步。 当UserB决定接管时,步骤2的php代码已经结束(您的提示问题)。您必须编写专用的代码来获得UserB回答的问题(这与您准备的javascript有关)。

无论如何,您都不会检查任何写访问权限,因此,一旦UserB接管然后注销,UserA仍将保持开放连接,但没有写访问权限。如果UserB重新连接,则会再次提示您接管不存在的内容(UserA的写访问权限已消失)。