Kzq*_*qai 2 javascript php spam-prevention concurrent-processing
背景:好的,我在ninjawars.net上运行了一个传统的BBG.玩家可以对通过表格帖子初始化的其他玩家进行"攻击".本质上,我们可以简化情况假装有一个页面,让我们称之为attack.php,用一个巨大的"ATTACK"表单发送到另一个php页面,让我们称之为accept_attack.php,第二页执行攻击功能,让我们说杀死其他玩家1,2或3.服务器运行PHP5,Postgresql,Apache
问题:
需要的解决方案:
那么如何防止某个脚本的同一处理一次性重复执行?
Php,社会工程和/或javascript/jQuery解决方案首选(可能大约是那个顺序).
编辑:基于答案,这是我做的(可能在压力测试之前)解决它:会话答案似乎最简单/最易于理解,因此我使用了该数据存储.我测试了它似乎工作,但可能有一些方法,我不知道.
$recent_attack = null;
$start_of_attack = microtime(true);
$attack_spacing = 0.2; // fraction of a second
if(SESSION::is_set('recent_attack')){
$recent_attack = SESSION::get('recent_attack');
}
if($recent_attack && $recent_attack>($start_of_attack-$attack_spacing)){
echo "<p>Even the best of ninjas cannot attack that quickly.</p>";
echo "<a href='attack_player.php'>Return to combat</a>";
SESSION::set('recent_attack', $start_of_attack);
die();
} else {
SESSION::set('recent_attack', $start_of_attack);
}
Run Code Online (Sandbox Code Playgroud)
如果有方法可以改进那些或可利用的方式(除了对我来说显而易见的事情,回应的东西不是一个很好的逻辑分离,我很想知道.沿着这些方向,社区维基编辑.
虽然womp的Post-Redirect-Get模式将解决一些问题,如果他们故意游戏提交过程,那么我怀疑它会阻止问题,除了反对懒惰(如链接文章中所述,302响应之前的提交将是多个因为重定向尚未发生).
相反,您可能最好在攻击页面上放置一些不易复制的信息令牌.当您接受攻击时,将攻击推送到数据库队列表中.具体来说,在排队时存储发送到攻击页面的信息令牌,并在排队攻击之前检查该令牌是否已被使用.
一个简单的令牌来源是运行随机数生成器并将它们放入表中的结果.为每个攻击页面加载提取下一个数字,并验证该数字最近是否已分发.您可以在攻击页面加载时重新填充令牌,并根据您的策略使"未使用"令牌到期,以便在"过时"之前页面可用多长时间.
通过这种方式,您可以生成一组有限的"有效"令牌,在攻击页面上发布这些令牌(每页一个),并验证它们是否已在攻击处理页面上使用过令牌.为了创建重复攻击,玩家必须确定哪些令牌有效...重复相同的帖子将失败,因为令牌已被消耗.使用BigInt和一个体面的伪随机数生成器,搜索空间使它不太容易规避.(注意,您需要围绕令牌验证和更新的事务,以确保使用此方法成功.)
如果您有需要登录的用户帐户,则可以在用户表上生成并存储这些令牌(同样,使用围绕这些步骤的数据库事务).然后,每个用户一次只能有一个有效的令牌,并且会以类似的方式捕获多个提交.