cube.js基于层级用户ID动态过滤数据实现行级权限的问题咨询
可以实现,你只需要借助Cube.js内置的SECURITY_CONTEXT(安全上下文)功能,配合你表中的ltree类型path字段做路径匹配,不需要额外编写JS业务代码,仅修改Cube模型配置即可。
第一步:先修正原有模型的语法错误
你现有代码存在两处小问题会导致模型加载失败:
- Writers模型中关联Publications时,表名拼写错误,
${Publication}应该改为${Publications} - 两个模型的配置对象末尾都漏了闭合的
}
第二步:修改Publications模型增加动态权限过滤逻辑
直接用以下代码替换你原来的两个模型代码即可:
cube(`Writers`, { sql: `SELECT * FROM public.writers`, preAggregations: {}, joins: { Publications: { sql: `${CUBE}.id = ${Publications}.writer_id`, relationship: `hasMany` } }, measures: { count: { type: `count`, drillMembers: [id, name] } }, dimensions: { id: { sql: `id`, type: `number`, primaryKey: true }, role: { sql: `role`, type: `string` }, name: { sql: `name`, type: `string` }, path: { sql: `path`, type: `string` } } }); cube(`Publications`, { sql: `SELECT * FROM public.publications WHERE -- ADMIN/EDITOR角色可以查看全部内容 (SELECT role FROM public.writers WHERE id = ${SECURITY_CONTEXT.writer_id.sql()}::INT) IN ('ADMIN', 'EDITOR') OR -- 其他角色仅可查看自己和下属子树的内容,用ltree的<@操作符匹配子路径 EXISTS ( SELECT 1 FROM public.writers w WHERE w.id = public.publications.writer_id AND w.path <@ (SELECT path FROM public.writers WHERE id = ${SECURITY_CONTEXT.writer_id.sql()}::INT) ) `, preAggregations: {}, joins: { Writer: { sql: `${CUBE}.writer_id = ${Writers}.id`, relationship: `hasOne` } }, measures: { count: { type: `count`, drillMembers: [id, publicationName, published] }, totalWordLength: { type: `sum`, sql: `word_length` } }, dimensions: { id: { sql: `id`, type: `number`, primaryKey: true }, publicationName: { sql: `publication_name`, type: `string` }, wordLength: { sql: `word_length`, type: `number` }, published: { sql: `published`, type: `time` } } });
第三步:在Playground中测试验证
你可以直接在Cube.js Developer Playground的右上角「Security Context」输入框中传入用户ID参数,格式为JSON:
比如测试用户3的权限,就输入{"writer_id": 3},查询到的出版物只会是ID为3、6的内容;
测试用户4的权限就输入{"writer_id":4},查询到的出版物只会是ID为4、5的内容;
测试管理员/编辑角色的用户,输入{"writer_id": 1}或者{"writer_id":2},可以看到全部6条出版物数据。
内容的提问来源于stack exchange,提问作者equatorial_daydreamer
相关产品推荐
相关产品推荐

