MySQL和Socket.IO –泛洪数据库>重复事务

时间:2018-12-17 14:16:04

标签: mysql node.js sockets spam-prevention

我不确定应该在哪里发布我的问题以及它背后的问题,但是我会在这里尝试一下。

前一段时间,我有一个小项目,用户可以在思考上花钱。这些硬币作为余额存储在我的MySQL数据库中的用户帐户中。前端使用socket.io连接到后端,节点应用程序使用常规的mysql模块与数据库进行通信。

问题: 不幸的是,一段时间后,我发现可以使用socket.io连接向节点应用程序泛洪/发送垃圾邮件(或多次打开网站以获取相同的结果),以减慢mysql查询的速度。这就是为什么可以将用户拥有的硬币花费两次或更多的原因。

正常的工作流程是:

Request to DB
check balance
if balance > 0
    spend coins
        reduce coins in DB
else
    reject

请求结束

如何两次使用硬币:(问题

Request to DB
Request to DB
    check balance
    check balance
    if balance > 0
    if balance > 0
        spend coins
        spend coins
        reduce coins in DB
        reduce coins in DB
    else
        reject
Request end
Request end

通过更新余额之前可以到达花费硬币的代码。

问题: 如何防止用户这样做?使用请求限制器仅适用于使用相同IP的用户,因此脚本不足应该无法达到我上面提到的目标。人们使用带有不同IP的小型僵尸网络怎么办?

如果我有解决该问题的方法,则可以再次启动该项目。

1 个答案:

答案 0 :(得分:1)

一种解决方案是使用select for update ... where user = XXX锁定check balance

另一种解决方案是添加一个version列。然后get balance and version,(假设顶点为n),spendreduce coins and set version= n+1 where version == n,则后面的填充失败。在此解决方案中,您应该在spend coins之后reduce succeeded.

这些只是一般的解决方案,仅供参考,因为我对socket.io不熟悉。