2

I want to make a Mongo FindAndModify request which finds a user by email and password and then updates it in one request, to be atomic. With basic MD5 hashed passwords and predefined salt I'd calculate hash before a request and make a following request:

db.people.findAndModify( {
    query: { email: "a@a.com", password: "<hashed value>"},
    update: { $set: { myField: "myNewValue" } }
} );

But bcrypt passwords are not the same every time because different salts are used on each hash generation so this approach doesn't work. Currently I have to find a user just by email and check his password in code with BCrypt.checkPassword function and, if it returns true, update my value in database. So I end up doing 2 requests and it's not atomic in Mongo.

So is there a way to do that in one MongoDB request (compare with bcrypt hash and update)? (I've seen an article on Mongo website about how to manually implemente 2-phase commit but wondering if there is a clean and nice solution).

makados
  • 149
  • 1
  • 3
  • 11
  • No, there's not a way to do that atomically (or as a transaction) if you need to run code between the find and update. If you add a "version" or timestamp field to a `people` document, it might be a reasonable alternative. – WiredPrairie Jun 20 '13 at 01:43
  • Could you elaborate more on version or timestamp field? I don't see how that helps. – makados Jun 20 '13 at 07:33
  • Add a version field which is retrieved as part of the password check. Increment it on the client and perform an update in a second step only if the version is the same. If another client has updated it, it won't match, so it will fail. – WiredPrairie Jun 20 '13 at 10:40

0 Answers0