uni-app jql聚合操作时报错 password.read权限校验未通过

uni-app jql聚合操作时报错 password.read权限校验未通过

项目 信息
产品分类 uniCloud/App
版本 HBX版本为3.1.22,uni-id为最新版
项目创建方式 使用最新的uni-id-users表schema

操作步骤:

如BUG 描述

预期结果:

如BUG 描述

实际结果:

如BUG 描述

bug描述:

HBX版本为3.1.22,uni-id为最新版,使用的最新的uni-id-users表schema

使用联表进行聚合操作,主表为自定义的表,副表为uni-id-users,主表副表所有权限设为true。主表foreignKey设置如下:  
"user_id": {  
      "foreignKey": "uni-id-users._id"  
 }
db.collection('tuan,uni-id-users')  
                            .aggregate()  
                            .geoNear({  
                                distanceField: 'distance', // 输出的每个记录中 distance 即是与给定点的距离  
                                spherical: true,  
                                near: new db.Geo.Point(res.longitude, res.latitude),  
                                distanceMultiplier: 1 / 1000, //将米换算为千米  
                                key: 'OriginLocation',   
                                includeLocs: 'OriginLocation',   
                            })  
                            .project({  
                                "user_id.password":0  
                            })   
                            .end()

报错为:PERMISSION_ERROR, [tuan.user_id.password.read]权限校验未通过
我已经用project过滤掉了password,为什么还报权限未通过?请问该如何解决该问题?


更多关于uni-app jql聚合操作时报错 password.read权限校验未通过的实战教程也可以访问 https://www.itying.com/category-93-b0.html

5 回复

这是bug吗?需要使用geonear对表“tuan”中的数据从近到远排序,又需要读取表“uni-id-users”里面的用户信息,该如何实现?呢?

更多关于uni-app jql聚合操作时报错 password.read权限校验未通过的实战教程也可以访问 https://www.itying.com/category-93-b0.html


使用云函数操作云数据库能否实现这个场景?

云函数中可以,clientDB中不行,geoNear只能在第一阶段,可能会影响权限判断,所以project内的字段过滤不会对权限校验生效

最新版 HX也会报这个错,反复测试了好久,这个方案可行: 1 除了要新版 2 需要指定字段,不能带password: jql要这样写: db.collection(‘uni-id-users’).field("_id,ali_openid,apple_openid,avatar,comment,department_id,email,email_confirmed,gender,inviter_uid,nickname,status,username,wx_openid,wx_unionid,info").where({wx_unionid:uni.getStorageSync(‘openid’)}).get({getOne:true}).then((res) => { ----以上在百度和微信小程序中测试成功,这个问题之前没有出现,应该是哪方改版之后把之前成功发布的搞报错了

这是一个典型的权限校验问题。虽然你在聚合查询的project阶段过滤了user_id.password字段,但权限校验发生在数据读取阶段,早于project阶段。

问题原因:

  1. uni-id-users表的password字段默认有严格的权限控制
  2. 即使你最终不返回password字段,只要查询涉及到了这个字段的读取,就会触发权限校验
  3. 聚合查询中的联表操作会尝试读取所有关联字段,包括password

解决方案:

方案一:修改uni-id-users表schema权限(推荐) 在uni-id-users表的schema.json中,为password字段添加聚合查询权限:

"password": {
  "bsonType": "string",
  "title": "密码",
  "forceDefaultValue": {
    "$env": "password"
  },
  "permission": {
    "read": false,
    "aggregate": true  // 添加这一行
  }
}

方案二:使用lookup替代联表查询 将联表查询改为聚合查询中的lookup操作:

db.collection('tuan')
  .aggregate()
  .geoNear({
    distanceField: 'distance',
    spherical: true,
    near: new db.Geo.Point(res.longitude, res.latitude),
    distanceMultiplier: 1 / 1000,
    key: 'OriginLocation',
    includeLocs: 'OriginLocation',
  })
  .lookup({
    from: 'uni-id-users',
    localField: 'user_id',
    foreignField: '_id',
    as: 'userInfo'
  })
  .project({
    "userInfo.password": 0
  })
  .end()

方案三:使用getTemp进行客户端查询 如果不需要服务端聚合,可以在客户端分别查询:

const tuanRes = await db.collection('tuan')
  .where(condition)
  .getTemp()

const userRes = await db.collection('uni-id-users')
  .field('_id,nickname,avatar') // 明确指定需要的字段
  .getTemp()

const result = await db.collection(tuanRes, userRes)
  .get()
回到顶部