我不知道我应该在哪里发布问题和背后的问题,但是我会在这里尝试一下。
前一段时间,我有一个小型项目,用户可以花硬币在思考上。这些硬币被存储在我的MySQL数据库中的用户帐户上。前端使用socket.io
连接到后端,并使用常规mysql
模块与数据库通信的节点应用程序。
​
问题:不幸的是,过了一会儿,我发现可以使用socket.io连接(或多次打开网站以获取相同结果),以降低MySQL Querys。这就是为什么可以花两次或更多的用户花费硬币的原因。
正常的工作流就像:
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的人,因此Scriptkiddys应该无法达到我上面提到的内容。那人们使用带有不同IP的小型僵尸网络呢?
​
如果我有解决这个问题的解决方案,我可以再次开始该项目。
一种解决方案是使用select for update ... where user = XXX
锁定check balance
。
另一个解决方案是添加version
列。然后 get balance and version
(假设Verison是N),spend
,reduce coins and set version= n+1 where version == n
,然后填充失败。在此解决方案中,您应在reduce succeeded.
之后进行spend coins
。
这些仅是一般解决方案仅作为参考,因为我不熟悉socket.io。