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
这是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阶段。
问题原因:
- uni-id-users表的password字段默认有严格的权限控制
- 即使你最终不返回password字段,只要查询涉及到了这个字段的读取,就会触发权限校验
- 聚合查询中的联表操作会尝试读取所有关联字段,包括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()

