Chris
Chris

Reputation: 1094

How to guard against repeated request?

we have a button in a web game for the users to collect reward. That should only be clicked once, and upon receiving the request, we'll mark it collected in DB.

we've already blocked the buttons in the client from repeated clicking. But that won't help if people resend the package multiple times to our server in short period of time.

what I want is a method to block this from server side.

we're using Playframework 2 (2.0.3-RC2) for server side and so far it's stateless, I'm tempted to use a Set to guard like this:

if processingSet has userId then BadRequest
else put userId in processingSet and handle request
     after that remove userId from that Set

but then I'd have to face problem like Updating Scala collections thread-safely and still fail to block the user once we have more than one server behind load balancing.

one possibility I'm thinking about is to have a table in DB in place of the processingSet above, but that would incur 1+ DB operation per request, are there any better solution~?

thanks~

Upvotes: 3

Views: 196

Answers (2)

Brian Smith
Brian Smith

Reputation: 3381

Given that you're using Mongo and so don't have transactions spanning separate collections, I think you can probably implement this guard using an atomic operation - namely "Update if current", which is effectively CompareAndSwap.

Assuming you've got a collection like "rewards" which has a "collected" attribute, you can update the collected flag to true only if it is currently false and if that operation doesn't fail you can proceed to apply the reward knowing that for any other requests the same operation will fail.

Upvotes: 3

biesior
biesior

Reputation: 55798

Additional DB operation is relatively 'cheap' solution in that case. You should use it if you'e planning to save the buttons state permanently.

If the button is disabled only for some period of time (for an example until the game is over) you can also consider using the cache API however keep in mind that's not dedicated for solutions which should be stored for long time (it should not be considered as DB alternative).

Upvotes: 3

Related Questions