环回如何从用户基础模型获取数据

时间:2017-03-09 11:05:00

标签: node.js loopbackjs strongloop loopback

我正在学习Loopback,我想知道最好的环回实践。 我有一个基于用户默认模型和跟随模型的成员模型。会员可以有很多粉丝。

{
  "name": "Member",
  "base": "User",
  "idInjection": true,
  "options": {
    "validateUpsert": true
  },
  "properties": {
    "nickname": {
      "type": "string"
    }
  },
  "validations": [],
  "relations": {
    "messages": {
      "type": "hasMany",
      "model": "Message",
      "foreignKey": ""
    },
    "followers": {
      "type": "hasMany",
      "model": "Member",
      "foreignKey": "followeeId",
      "through": "Follow"
    },
    "following": {
      "type": "hasMany",
      "model": "Member",
      "foreignKey": "followerId",
      "through": "Follow"
    }
  },
  "acls": [
    {
      "accessType": "*",
      "principalType": "ROLE",
      "principalId": "$everyone",
      "permission": "ALLOW"
    }
  ],
  "methods": {}
}

这是我的Follow模型

{
  "name": "Follow",
  "base": "PersistedModel",
  "idInjection": true,
  "options": {
    "validateUpsert": true
  },
  "properties": {},
  "validations": [],
  "relations": {
    "follower": {
      "type": "belongsTo",
      "model": "Member",
      "foreignKey": ""
    },
    "followee": {
      "type": "belongsTo",
      "model": "Member",
      "foreignKey": ""
    }
  },
  "acls": [],
  "methods": {}
}

我希望该成员能够获取其关注者,但实现这一目标的最佳方式是什么:

  • 我应该修改默认用户ACL,以便能够从Member with /Members/{id}/followers(当前被阻止)获取数据吗?
  • 我应该为成员创建一个新的远程方法来实现这个目标吗?最好的方法是什么?我是否应该检查成员身份,就像我对其他方法一样使用了accessstoken(下面的示例)?

    Professionaldemand.createDemand = function (accessToken, cb) {
    //Rejection if not an authenticated User
    if (!accessToken) {
        return errorUtility.CallbackError("Access Token is not valid", 400, cb);
    }
    
    var currentDate = new Date();
    Professionaldemand.create({ Acceptation: false, CreationDate: currentDate, memberId: accessToken.userId },
        function (err) {
            if (err) {
                return errorUtility.CallbackError("Professionaldemand creation error", 400, cb);
            }
        }, cb(null));
    };
    

方法定义:

Professionaldemand.remoteMethod(
    'createDemand', {
        http: {
            path: '/createDemand',
            verb: 'post'
        },
        description: ["Permits client to ask for a professional permission"]
        ,
        accepts: [
            {
                arg: 'access_token',
                type: 'object',
                http: function (ctx) {
                    return ctx.req.accessToken;
                }
            }
        ]
    }
);

1 个答案:

答案 0 :(得分:0)

您的模型定义和关系看起来很不错。

需要更好地分离的是来自业务逻辑的访问控制。

需要使用每个模型定义中的acls属性强制执行访问控制。它不应该由您的远程方法处理,因为否则您将需要为每个远程方法重复代码,并且您可能有更好的事情要做:)

ACLS

首先,对于每个模型,将一切都拒绝给每个人是一种好习惯。确保您不会在API中留下漏洞是一种很好的做法。

然后,为每种特定路线或方法授权特定类型的用户。 它的工作原理是因为非常具体的acl规则优先于广泛的acl规则。

例如:

  1. Member all methods all users Deny
  2. Member __addFollowower__ $owner Allow
  3. 这样,远程方法Member.addFollower将仅允许成员$所有者,基本上是会员本人。他将无法代表其他人添加关注者。

    获取粉丝

      

    我希望该成员能够获取其关注者,但实现这一目标的最佳方法是什么。 [...]我应该为会员创建一个新的远程方法来实现这个目标吗?

    在这种情况下,您不一定需要创建远程方法,实际上它与您的关系生成方法是多余的。你只需致电

    GET api/Member/:id/followers?access_token=e23saa2ragkuljkh2...

    如果您不想跟踪:id客户端,也可以使用

    GET api/Member/me/followers?access_token=e23saa2ragkuljkh2...

    在这种情况下,loopback将使用访问令牌来确定登录用户的ID,并用此ID替换me

    PS:这是在你configured loopback to support this的条件下工作的。