阻止用户执行两次操作

时间:2010-04-17 11:20:48

标签: php javascript mysql

我们在用户执行两次特定操作时遇到一些问题,我们有一种机制可以确保用户不能这样做,但不知怎的,它仍然会发生。以下是我们当前机制的工作原理:

  1. 客户端:点击一下后该按钮将被停用。
  2. 服务器端:我们在URL中有一个密钥哈希,将根据存储在SESSIONS中的密钥进行检查,一旦匹配,密钥就会被删除。
  3. 数据库方:执行操作后,会有一个要标记的字段,表明用户已完成操作。
  4. 然而,通过所有这些措施,仍然有用户能够执行两次操作,是否有更安全的方法?

    以下是数据库端的部分代码:

    $db->beginTransaction();
    // Get the user's datas
    $user = $db->queryRow("SELECT flag FROM users WHERE userid = {$auth->getProperty('auth_user_id)}");
    if ($user['flag'] != 0) {
        $db->rollback();
        // Return with error
        return false;
    }
    // Proceed with performing the action
    // --- Action Here ---
    // Double checking process, the user data is retrieved again
    $user = $db->queryRow("SELECT flag FROM users WHERE userid = {$auth->getProperty('auth_user_id)}");
    if ($user['flag'] != 0) {
        $db->rollback();
        // Return with error
        return false;
    }
    // --- The final inserting query ---
    // Update the flag
    $db->query("UPDATE users SET flag = 1 WHERE userid = {$auth->getProperty('auth_user_id)}");
    $db->commit();
    return true;
    

3 个答案:

答案 0 :(得分:1)

很高兴看到你已采取一切措施打败坏人。谈到坏人:

<强>最后:

我建议您查看:

<强> OWASP PHP Project

OWASP PHP项目的目标(OWASP PHP项目路线图)旨在使开发人员,系统管理员和应用程序架构师能够构建和部署使用PHP编程语言构建的安全应用程序。

答案 1 :(得分:0)

JS方法和Hash方法可能会被一些臭名昭着的人欺骗,但第三种方法似乎非常好,以保护冗余。必须有一些编程漏洞才能通过这个。

为什么不检查插入值的页面上的标志字段,而不是用户执行操作的位置(如果您现在正在执行此操作)

答案 2 :(得分:0)

伪代码如下:

<?

$act_id; // contains id of action to be executed

$h = uniqid('');

// this locks action (if it is unlocked) and marks it as being performed by me.
UPDATE actions SET executor = $h WHERE act_id = $act_id AND executor = ''; 

SELECT * FROM actions WHERE executor = $h;

//
// If above query resulted in some action execute it here
//

// if you want to allow for executing this exact action in the future mark it as not executed
UPDATE actions SET executor = '' WHERE act_id = $act_id; 

重要的事情:

  • 第一个查询应该是更新声明 如果它还没有给我的动作 无人认领。
  • 第二个应该是查询 抓住行动来执行但只是 如果有人声称我。