简体   繁体   English

防止用户两次执行操作

[英]Prevent Users from Performing an Action Twice

We have some problems with users performing a specific action twice, we have a mechanism to ensure that users can't do it but somehow it still happens. 用户在两次执行特定操作时会遇到一些问题,我们有一种机制可以确保用户无法执行操作,但仍会以某种方式发生。 Here is how our current mechanism works: 这是我们当前机制的工作方式:

  1. Client side: The button will be disabled after 1 click. 客户端:单击1次后,该按钮将被禁用。
  2. Server side: We have a key hash in the URL which will be checked against the key stored in SESSIONS, once it matches, the key is deleted. 服务器端: URL中有一个密钥哈希,将对照存储在SESSIONS中的密钥进行检查,一旦匹配,就将其删除。
  3. Database side: Once the action is performed, there is a field to be flagged indicating the user has completed the action. 数据库端:执行操作后,将标记一个字段,指示用户已完成该操作。

However, with all these measures, still there are users able to perform the action twice, are there any more safer methods? 但是,通过所有这些措施,仍然有用户能够执行两次该操作,还有其他更安全的方法吗?

Here is the partial code for the database side: 这是数据库端的部分代码:

$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;

It is good to see that you have taken all measures to defeat the bad guys. 很高兴看到您已采取一切措施击败了坏蛋。 Speaking in terms of bad guys: 说到坏家伙:

Finally: 最后:

I would recommend to you to check out the: 我建议您检查一下:

OWASP PHP Project OWASP PHP项目

The OWASP PHP Project's goal (OWASP PHP Project Roadmap) is to enable developers, systems administrators and application architects to build and deploy secure applications built using the PHP programming language. OWASP PHP项目的目标(OWASP PHP项目路线图)旨在使开发人员,系统管理员和应用程序设计师能够构建和部署使用PHP编程语言构建的安全应用程序。

Well the JS method and Hash method may be cheated by some notorious guy, but 3rd method seems to be very good in order to protect the redundancy. JS方法和Hash方法可能被一些臭名昭著的家伙所欺骗,但是为了保护冗余,第3种方法似乎非常好。 There must be some programming flaw to get passed this. 要通过此程序,必须存在一些编程缺陷。

Why don't u just check the flag field on the page where you are inserting the values rather than where user performing the action (if you are doing it now) 您为什么不只检查页面上的标记字段,而不是在用户执行操作的位置(如果您现在正在执行操作),则在其中插入值

Pseudocode follows: 伪代码如下:

<?

$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; 

Important things: 重要的事:

  • First query should be update claiming the action for me if it is yet unclaimed. 如果尚未提出要求,则第一个查询应该是对我声明更新的操作。
  • Second should be query grabbing action to execute but only if it was claimed by me. 其次应该是执行查询抓取动作,但前提是我要求它执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM