You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 07:25:17