KeystoneJS 6中item对象访问及权限控制实现方案咨询
KeystoneJS 6 实现用户权限控制方案
前提准备
首先确保你的Blog和Post列表已经正确关联到User:
Blog列表需添加owner字段,关联到User:
owner: relationship({ ref: 'User', many: false })
Post列表需添加blog字段,关联到Blog:
blog: relationship({ ref: 'Blog', many: false })
1. 限制用户仅能修改/删除自己的Blog
定义权限函数,判断当前登录用户是否为Blog的所有者,然后配置到Blog列表的access中:
权限函数
const canManageOwnBlog = ({ session, item }) => { // 未登录用户直接拒绝 if (!session?.data) return false; // 对比当前用户ID与Blog的所有者ID return session.data.id === item.owner.id; };
配置Blog列表的权限与自动设置所有者
在Blog的list配置中,设置access和hooks(创建Blog时自动绑定当前用户为所有者):
export const Blog = list({ fields: { // 你的其他字段... owner: relationship({ ref: 'User', many: false }), }, access: { // 登录用户即可创建Blog create: ({ session }) => !!session?.data, // 仅所有者可修改/删除 update: canManageOwnBlog, delete: canManageOwnBlog, // 公开读取(可根据需求调整) read: () => true, }, hooks: { resolveInput: ({ operation, resolvedData, session }) => { // 创建Blog时自动绑定当前用户为所有者 if (operation === 'create') { return { ...resolvedData, owner: { connect: { id: session.data.id } }, }; } return resolvedData; }, }, });
2. 限制用户仅能为自己的Blog创建Post
创建Post时,需要验证用户要关联的Blog是否属于自己。由于创建时item对象不存在(Post还未生成),需通过context查询目标Blog的所有者:
权限函数
const canCreatePostForOwnBlog = async ({ session, context, resolvedData }) => { // 未登录用户直接拒绝 if (!session?.data) return false; // 获取要关联的Blog ID const targetBlogId = resolvedData.blog?.connect?.id; if (!targetBlogId) return false; // 查询目标Blog的所有者 const targetBlog = await context.db.Blog.findOne({ where: { id: targetBlogId }, select: { owner: { id: true } }, }); // 验证当前用户是否为该Blog的所有者 return targetBlog?.owner.id === session.data.id; };
配置Post列表的创建权限
在Post的list配置中,设置create权限为上述函数:
export const Post = list({ fields: { // 你的其他字段... blog: relationship({ ref: 'Blog', many: false }), }, access: { // 仅能为自己的Blog创建Post create: canCreatePostForOwnBlog, // 其他权限可根据需求调整,例如: // read: () => true, // update: ({ session, item }) => session.data.id === item.author.id || session.data.id === item.blog.owner.id, }, });
关于item对象的说明
你之前尝试的函数中访问item失败,可能是在create操作中使用了item:
item仅在update、delete、read操作的权限函数中存在,对应已有的数据库记录;create操作时,目标记录尚未生成,因此没有item对象,需通过resolvedData获取用户提交的关联数据,再结合context查询数据库验证权限。
内容的提问来源于stack exchange,提问作者Timo Martinson
相关产品推荐
相关产品推荐

