使用事务交换两个值 - 我不认为我可以安全地做到这一点

时间:2013-11-21 05:29:45

标签: security transactions firebase

我正在尝试使用firebase两个交换两个值,无论我做什么,我似乎无法找到任何安全的东西。

UserA在23,userB在第5位,我想交换这两个数字..

显然我应该为此使用一个事务,因为一个值依赖于另一个。目前我的数据设置如下 -

-world
    -pos23
        -userA
    -pos5
        -userB
    -pos98
        -otherUser
    etc...

显然我可以用不同的方式构建它 - 反转用户和位置,但它似乎没有帮助我的问题 -

如果我想对这两个用户进行交易,我必须将其应用于“世界”,我无法将其应用到某个位置,因为我需要访问其他位置。要做一个事务,我必须提供对整个世界的读写访问权限,这意味着我应用于在较低级别修改数据的方式的任何类型的安全规则都是无用的 - 世界级别的读取和写入会覆盖它。如果我想这样做,那么userC就不能被移动了。

根据我的实验,此安全规则使我执行的任何事务无效,

{
  "rules": {
    ".read": true,
    "$anyPosition": {
      ".write": true,
    },
  }
}

我认为允许访问结构中的任何内容,但它实际上失败了,因为我没有写:在世界级别为true。它允许我使用set而不是事务。

我可能会以错误的方式解决这个问题,我应该如何安全地交换两个值?

1 个答案:

答案 0 :(得分:0)

您的假设是正确的,即在使用两个单独的路径时,您无法在单个操作中访问这两个值。没有惊喜;操作必须在world上。

看起来似乎priorities,可能是比实际移动数据中的用户记录更好的解决方案。但是我并不完全理解你的用例,所以我不会质疑你的理由,只是指出它们以防它们没有被考虑过。

我确信你已经意识到你可以通过简单地直接交换来强制采用非原子方法,适用于除金钱和视频游戏分数之外的大多数东西:

function swapValues( ref, keyA, keyB ) {
   ref.child(keyA).once('value', function(snapA) {
      ref.child(keyB).once('value', function(snapB) {
          snapA.ref().set(snapB.val());
          snabB.ref().set(snapA.val());
      });
   });
}

只需轻微编辑,您就可以使用update以原子/交易安全的方式一次性获得两个操作:

function swapValues( ref, keyA, keyB ) {
   ref.child(keyA).once('value', function(snapA) {
      ref.child(keyB).once('value', function(snapB) {
          var updateVal = {};
          updateVal[ snapA.name() ] = snapB.val();
          updateVal[ snapB.name() ] = snapA.val();

          ref.update( updateVal );
      });
   });
}