代码之家  ›  专栏  ›  技术社区  ›  ffflabs

环回3:检查模型是否存在并且它是我的

  •  0
  • ffflabs  · 技术社区  · 6 年前

    使用环回ACL的I用于设置模型访问规则,以便只有所有者可以检查模型详细信息或修改它们:

    {
      "accessType": "*",
      "principalType": "ROLE",
      "principalId": "$owner",
      "permission": "ALLOW"
    },
    {
      "accessType": "*",
      "principalType": "ROLE",
      "principalId": "$everyone",
      "permission": "DENY"
    },
    

    • 我从物联网设备上得到身份证
    • 我把这个ID发送给API
      • 如果它是注册的而不是我的,那么应该告诉我不能与设备交互
      • 如果它已经注册并且是我的,那么我会得到一个回复,让我知道我已经认领了这个。

    我似乎不能单靠状态码来做这件事。

    *尝试一:使用*存在**

    如果我允许任何经过身份验证的用户检查模型是否存在:

    {
      "accessType": "EXECUTE",
      "principalType": "ROLE",
      "principalId": "$authenticated",
      "permission": "ALLOW",
      "property": "exists"
    }
    

    如果模型存在,它将返回状态代码200,如果不存在,则返回状态代码404。因此,我需要执行第二个查询(例如使用 findById

    尝试二:使用findById

    但是,查询不存在的模型 也将返回状态代码403

    尝试三:为其他经过身份验证的用户启用findById

    芬德比德

    {
      "accessType": "READ",
      "principalType": "ROLE",
      "principalId": "$authenticated",
      "permission": "ALLOW",
      "property": "findById"
    }
    

    如果模型不存在,则返回404;如果存在,则返回其他相关实体的所有细节,eventhough属于其他用户。

    就是这样。似乎我要做一个特殊的远程方法来处理这个案例,但是我很困惑,这听起来像是一个相当常见的场景,我只想得到404/403/200来允许前端采取相应的行动。

    1 回复  |  直到 6 年前
        1
  •  0
  •   ffflabs    6 年前

    好吧,如果有人遇到这个问题,我最终用远程方法解决了。

    它将上下文作为请求的参数,因此在模型json文件中定义为:

     "methods": {
        "hasclaimed": {
            "accepts": [{
                    "arg": "deviceId",
                    "type": "number",
                    "required": true
                },
                {
                    "arg": "res",
                    "type": "object",
                    "http": {
                        "source": "res"
                    }
                },
                {
                    "arg": "options",
                    "type": "object",
                    "http": "optionsFromRequest"
                }
            ],
            "returns": {
                "arg": "data",
                "type": "object",
                "root": true
            },
            "http": {
                "verb": "GET",
                "path": "/hasclaimed/:deviceId"
            }
        }
    }
    

    在javascript文件中:

    Customer.hasclaimed = function(deviceId, res, options) {
        const Device = this.app.models.Device;
        return Device.findById(deviceId, null, options).then(device => {
          const token = options && options.accessToken;
          const userId = token && token.userId;
          if (!userId) {
            res.status(401);
            return {};
          }
          if (!device) {
            res.status(204);
            return {};
          }
    
          console.log('(%s) %j', userId, device.idCustomer);
    
          if (device.idCustomer !== userId) {
            res.status(403);
            return {};
          }
          res.status(200);
          return device;
        });
      };
    

    所以基本上:

    • response对象,以便设置自定义头

    使用客户端点,我调用 GET customer/hasclaimed/:deviceId

    如果用户未登录,将收到401。 一个现有的设备将返回200(及其属性)给所有者,403它设备存在,但它不是他的。