【问题标题】:Parse Pointer Permissions don't allow create解析指针权限不允许创建
【发布时间】:2016-01-08 02:57:23
【问题描述】:

我已经按照this walkthrough 的每一步,但是当我尝试创建一个新行时,我得到一个 403:

代码:119

消息:“此用户不允许执行创建 消息操作。您可以在数据浏览器中更改此设置。”

我的代码:

Messages = Parse.Object.extend("Messages")
var message = new Messages();
message.set("sender", Parse.User.current());
message.set("receiver", *anotherUser*);
message.set("subject", "foo")
message.set("body", "bar")
message.save()
.then(
  function(message){
    console.log("success!")
  },function(error){
    console.log("error: ", error);
});

我的 CLP 设置如下:

好像是其他人发布了the same issue in a google group。我们缺少什么?

【问题讨论】:

  • 你检查过Parse.User.current()的值是多少吗?我的猜测是它返回了一个 nil 用户。另外,我一直用PFUser.currentUser(),所以也可以试试
  • 只是仔细检查了——我在保存之前console.log 将其取出,它是一个具有 id 的有效用户对象。
  • request.user有区别吗?也尝试记录一下,看看它们是否不同
  • 它们是一样的。刚刚按要求修改了我的云代码,并在我的日志中查看before_save triggered for Messages for user xxxx,其中xxxxsender 字段相同。
  • @Russell 您是否曾经使用过指针权限并让create 按预期工作?

标签: javascript security parse-platform


【解决方案1】:

我已将此作为 a bug 提交给 Parse (Facebook),他们回复:

我们已经设法重现了这个问题,它似乎是一个有效的错误。我们正在将其分配给适当的团队。

问题解决后,我将更新此答案。 如果此问题对您有影响,请订阅该错误,因为这将有助于确定修复的优先级。

更新

Facebook 回复:

事实证明,这实际上是设计使然。要创建一个对象,该类应该对其拥有公共创建权限

不幸的是,使用此解决方案,我可以“来自”任何其他用户(另一个用户设置为sender)创建一条消息。这是不可接受且无法使用的恕我直言。

【讨论】:

    【解决方案2】:

    这是自推出指针权限以来的一个错误,这实际上使它们无用。我的印象是,他们构建这个的想法是让开发人员一次性保护现有模式,但你当然需要它来为将来的创建工作。

    一种解决方法是结合旧的类级别权限和每行 ACL,同时注意不要禁用数据浏览器。假设您有“Puppy”和“Cat”类,并且都有一个名为“owner”的字段。

    1. 在您的数据浏览器中,对于每个需要拥有所有者字段的类,您将其 Puppy 和 Cat 的类级别权限分别设置为:

    公开 - 读取:是或否,取决于您的用例,写入:是

    为“所有者”添加指针权限 - 读取:是,写入:是(现在可以跳过,见下文)

    1. 然后在您的 cloud/main.js 中,您可以使用以下内容作为起点(下面我经常将其称为“类型”,抱歉)。

    2. 当 Parse 修复创建问题时,您删除公共写入类级别权限(上),保留指针权限,并去掉下面的解决方法代码。

    --

    var validateAndUpdateOwnerWritePerms = function(request){
        var object = request.object;
        var error = null;
        var owner = object.get('owner');
    
        if (!Parse.User.current()) {
            error = 'User session required to create or modify object.';
        } else if (!owner) {
            error = 'Owner expected, but not found.';
        } else if (owner && owner.id != Parse.User.current().id && !object.existed()) {
            error = 'User session must match the owner field in the new object.';
        }
    
        if (request.master) {
            error = null;
        }
    
        if (error) {
            return error;
        }
    
        if (object.existed()) {
            return null;
        }
    
        var acl = new Parse.ACL();
        acl.setReadAccess(owner, true);
        acl.setWriteAccess(owner, true);
    
        object.setACL(acl);
    
        return null;
    }
    
    // Wrapper that makes beforeSave, beforeDelete, etc. respect master-key calls.
    // If you use one of those hooks directly, your tests or admin
    // console may not work.
    var adminWriteHook = function(cloudHook, dataType, callback) {
        cloudHook(dataType, function(request, response) {
            if (request.master) {
                Parse.Cloud.useMasterKey();
            } else {
                var noUserAllowed = false;
                if (cloudHook == Parse.Cloud.beforeSave &&
                    (dataType == Parse.Installation || dataType == Parse.User)) {
                        noUserAllowed = true;
                }
                if (!noUserAllowed && !Parse.User.current()) {
                    response.error('Neither user session, nor master key was found.');
                    return null;
                }
            }
    
            return callback(request, response);
        });
    };
    
    // Set hooks for permission checks to run on delete and save.
    var beforeOwnedTypeWriteHook = function(type) {
        var callback = function (request, response) {
            var error = validateAndUpdateOwnerWritePerms(request);
            if (error) {
                response.error(error);
                return;
            }
            response.success();
        };
        return adminWriteHook(Parse.Cloud.beforeSave, type, callback);
        return adminWriteHook(Parse.Cloud.beforeDelete, type, callback);
    };
    
    beforeOwnedTypeWriteHook('Puppy');
    beforeOwnedTypeWriteHook('Cat');
    

    【讨论】:

      【解决方案3】:

      不幸的是,解析指针权限在Create 上似乎无法正常工作。快速解决办法是允许Create 对Public 的权限。然后确保创建记录的用户与sender相同。因此,您需要在云代码中的 Messages 类的 beforeSave 触发器中执行手动检查,如果检查失败,则拒绝正在创建的记录。

      【讨论】:

      • 关于利用云代码的好主意,但最好尽可能使用 CLP 和 ACL。由于应用程序的当前用户正在创建消息对象,因此应该没有任何问题。我的猜测是Parse.User.current() 返回 nil 有错误
      • 那么授予create 权限有什么作用?
      • @Russell 正如我所说,不幸的是,当发件人创建记录时,指针权限不知何故不起作用。您需要在没有它们的情况下授予创建权限@@adamdport 通过授予创建权限,您可以让任何人在该类中创建记录。添加简单的云代码逻辑,现在只有发件人才能创建记录。当您获得预期的行为时,问题就解决了
      • @MoNazemi 我的意思是create 作为指针 CLP 的作用,而不是公开的。我毫不怀疑我可以通过 Cloud Code 手动管理这些权限,但我想尽可能利用 Parse 的 OTC 解决方案。
      • 遗憾的是它什么也没做!创建似乎根本不起作用。据我所知,给出的解决方法是解决它的唯一方法。这对我来说应该作为一个错误报告给 Parse。
      猜你喜欢
      • 2015-02-08
      • 2011-05-07
      • 2013-03-27
      • 1970-01-01
      • 2021-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-21
      相关资源
      最近更新 更多