KeystoneJS中管理员用户访问控制配置无效问题排查
KeystoneJS 管理员访问控制不生效问题解决
我在学习KeystoneJS时,给标记为管理员的用户配置后端访问控制遇到了问题。参考官方手册的TypeScript示例转成JavaScript后,数据库内的管理员用户无法触发权限控制——服务器启动后管理路由正常加载,但控制台无任何报错信息。
下面是我当前的配置代码,以及针对性的解决步骤:
现有代码问题分析
首先存在两个核心错误:
- 文件名与模型内容完全颠倒:
post.js实际定义的是User模型,user.js实际定义的是Post模型,导致权限规则应用到了错误的列表上 - 关联字段引用错误:模型间的关联关系未正确对应
- ES模块与CommonJS混用:
keystone.js使用了export default,但其他文件用require导入,在Node.js环境下会导致加载异常
修正后的代码
1. keystone.js(修正导出方式)
// Requiring configuration modules const { config } = require("@keystone-6/core"); const { withAuth, session} = require("./auth"); // Requiring models const User = require("./models/User"); const Post = require("./models/Post"); // Initializing configuration and settings up module.exports = config( withAuth({ db: { provider: 'mysql', url: 'mysql://root:Kist%40Ride%23007@localhost:3306/keystone', }, lists: { User, Post }, session, ui: { isAccessAllowed: (context) => !!context.session?.data, }, }) );
2. auth.js(无需修改,确认sessionData配置)
const { createAuth } = require("@keystone-6/auth"); const { statelessSessions } = require("@keystone-6/core/session"); const { withAuth } = createAuth({ listKey: 'User', identityField: 'email', sessionData: 'isAdmin', secretField: 'password', initFirstItem: { fields: ['name', 'email', 'password'] } }); let sessionSecret = '-- DEV COOKIE SECRET; CHANGE ME --'; let sessionMaxAge = 60 * 3; const session = statelessSessions({ maxAge: sessionMaxAge, secret: sessionSecret }); module.exports = { withAuth, session };
3. models/User.js(原post.js内容,修正关联引用)
const { list } = require("@keystone-6/core"); const { allowAll } = require("@keystone-6/core/access"); const { password, text, relationship, checkbox } = require("@keystone-6/core/fields"); module.exports = list({ access: allowAll, fields: { name: text({ validation: { isRequired: true } }), email: text({ validation: { isRequired: true }, isIndexed: 'unique' }), password: password({ validation: { isRequired: true } }), isAdmin: checkbox(), posts: relationship({ ref: 'Post.author', many: true }), } });
4. models/Post.js(原user.js内容,修正权限规则与关联)
const { list } = require("@keystone-6/core"); const { allowAll } = require("@keystone-6/core/access"); const { document } = require("@keystone-6/fields-document"); const { text, timestamp, relationship, select, checkbox } = require("@keystone-6/core/fields"); // 明确判断isAdmin为true,避免undefined等模糊值 const isAdmin = ({ session }) => session?.data.isAdmin === true; module.exports = list({ access: { operation: { create: isAdmin, update: isAdmin, delete: isAdmin, read: ({ session }) => !!session, // 登录用户可查看内容 } }, fields: { title: text(), isPublished: checkbox(), publishedAt: timestamp(), author: relationship({ ref: 'User.posts', many: false, }), content: document({ formatting: true, links: true, dividers: true, layouts: [ [1, 1], [1, 1, 1], [2, 1], [1, 2], [1, 2, 1], ], }), status: select({ options: [{ label: 'Published', value: 'published' }, { label: 'Draft', value: 'draft' }], defaultValue: 'draft', ui:{ displayMode: 'segmented-control' } }), } });
额外验证步骤
- 确认数据库中管理员用户的
isAdmin字段已设置为true - 清除浏览器缓存并重新登录,确保session数据更新
- 可在
isAdmin函数中添加日志调试,确认session数据:const isAdmin = ({ session }) => { console.log('当前Session数据:', session?.data); return session?.data.isAdmin === true; };
内容的提问来源于stack exchange,提问作者mastercordy
相关产品推荐
相关产品推荐

