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

KeystoneJS中管理员用户访问控制配置无效问题排查

KeystoneJS 管理员访问控制不生效问题解决

我在学习KeystoneJS时,给标记为管理员的用户配置后端访问控制遇到了问题。参考官方手册的TypeScript示例转成JavaScript后,数据库内的管理员用户无法触发权限控制——服务器启动后管理路由正常加载,但控制台无任何报错信息。

下面是我当前的配置代码,以及针对性的解决步骤:


现有代码问题分析

首先存在两个核心错误:

  1. 文件名与模型内容完全颠倒:post.js实际定义的是User模型,user.js实际定义的是Post模型,导致权限规则应用到了错误的列表上
  2. 关联字段引用错误:模型间的关联关系未正确对应
  3. 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'
            }
        }),
    }
});

额外验证步骤

  1. 确认数据库中管理员用户的isAdmin字段已设置为true
  2. 清除浏览器缓存并重新登录,确保session数据更新
  3. 可在isAdmin函数中添加日志调试,确认session数据:
    const isAdmin = ({ session }) => {
        console.log('当前Session数据:', session?.data);
        return session?.data.isAdmin === true;
    };
    

内容的提问来源于stack exchange,提问作者mastercordy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 16:35:12