通过登录系统可以知道当前请求来自哪个用户通过 Gateway系统可以统一校验 Token并把用户身份透传给下游服务。但是仅仅知道“这个人是谁”还不够。企业知识库真正关心的是另一个问题这个用户能不能访问这个资源比如A 用户能不能查看 B 用户创建的知识库普通用户能不能查看所有用户的问答日志用户上传文档时能不能往别人的知识库里上传用户提问时检索范围是不是只在自己的知识库内管理员为什么可以查看全局任务这些问题都属于资源隔离和权限边界。这一篇要讲清楚 KnowHub 如何在登录认证之后继续做用户资源隔离以及基础后台管理端如何建立在 USER / ADMIN 角色之上。01 登录认证不等于资源授权很多初学者会把“登录”和“有权限”混在一起。其实它们不是一回事。登录认证解决的是你是谁资源授权解决的是你能访问什么用户成功登录只能说明他是系统里的合法用户。它并不意味着这个用户可以访问所有知识库、所有文档和所有日志。举个例子。A 用户登录后Token 中的身份是userId 1 role USERB 用户创建了一个知识库kbId 100 userId 2A 用户如果请求GET /kb/100Gateway 只能判断 A 用户已经登录它并不知道 kbId100 属于谁。真正的判断必须在 knowledge-service 中完成查询 knowledge_base.id 100 判断 knowledge_base.user_id 是否等于当前 userId 如果不相等则拒绝访问这就是为什么企业系统不能只做登录还必须在业务层做资源归属校验。02 用户资源隔离的 4 个基本原则KnowHub 的资源隔离遵循几个原则。不相信前端传入的 userId前端传来的参数都可以被用户修改。所以用户侧接口不应该依赖前端传入的 userId而应该使用 Gateway 透传后由下游服务构造出的当前用户身份。也就是当前用户 UserContext.getUserId()而不是当前用户 request.getParameter(”userId”)所有用户侧查询都带当前 userId查询“我的知识库”时SQL 条件中必须包含当前用户 ID。逻辑类似select * from knowledge_base where user_id 当前用户ID and status ENABLED这样 A 用户只能看到自己的知识库。跨用户访问不要泄露资源信息如果 A 用户访问 B 用户的知识库系统可以返回无权限也可以返回资源不存在。很多系统会选择返回“资源不存在”这样可以减少资源探测风险。A 用户访问 /kb/100 但 kbId100 属于 B 用户 系统返回知识库不存在从用户体验看这和真的没有这个知识库类似从安全角度看攻击者无法判断这个 ID 是否真实存在。写操作更要先校验归属不仅查询要校验写操作更要校验。比如上传文档前先校验知识库是否属于当前用户。删除知识库前先校验知识库 owner。发起问答前先校验知识库 owner。重建索引前先校验文档是否属于当前知识库和当前用户。只有这样用户才不能把数据写进别人的资源里。03 知识库 owner 校验怎么做知识库是 KnowHub 中最核心的资源边界。在 knowledge_base 表中每条记录都应该有一个 user_id 字段。它表示这个知识库属于哪个用户。简化结构如下id user_id name description status created_at updated_at当用户访问某个知识库时knowledge-service 要做两件事1. 查询知识库是否存在 2. 判断 knowledge_base.user_id 是否等于当前用户 ID如果不相等就不能继续访问。创建知识库创建知识库时前端只需要提交名称和描述。用户 ID 不应该由前端传入而应该来自当前登录用户。流程如下前端提交 name、description - Gateway 校验 Token - knowledge-service 获取当前 userId - 创建 knowledge_base - knowledge_base.user_id 当前 userId这样用户无法伪造 owner。查询我的知识库查询列表时只返回当前用户自己的数据where user_id 当前 userId管理员查看全局知识库则走 /admin/** 管理端接口不和普通用户接口混用。查看知识库详情查看详情时除了按 ID 查询还要检查 owner。错误思路select * from knowledge_base where id kbId正确思路select * from knowledge_base where id kbId and user_id 当前用户ID重点是不能遗漏 owner 条件。knowledge_base 表设计user_id 是资源隔离的核心字段必须出现在索引中。CREATE TABLE knowledge_base ( id BIGINT NOT NULL AUTO_INCREMENT COMMENT 知识库ID, user_id BIGINT NOT NULL COMMENT 知识库owner用户ID, name VARCHAR(100) NOT NULL COMMENT 知识库名称, description VARCHAR(500) DEFAULT NULL COMMENT 知识库描述, status VARCHAR(32) NOT NULL DEFAULT ENABLED COMMENT 状态ENABLED/DISABLED/DELETED, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间, PRIMARY KEY (id), KEY idx_kb_user_status_updated (user_id, status, updated_at), KEY idx_kb_user_name (user_id, name) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT知识库表;idx_kb_user_status_updated 用于“查询我的知识库”这类高频接口idx_kb_user_name 可以辅助同一用户下的名称查询或名称查重。04 Redis owner 缓存设计知识库 owner 校验会被频繁使用。比如查询知识库详情。上传文档。查询文档列表。发起向量检索。发起 RAG 问答。如果每次都查 MySQL压力虽然不一定很大但链路会更长。KnowHub 使用 Redis 缓存知识库 owner减少重复查询。缓存 Key 设计owner 缓存 key 可以设计为rag:kb:owner:{kbId}例如rag:kb:owner:100value 保存 owner 用户 ID2查询流程校验知识库 owner 时流程如下1. 根据 kbId 读取 Redisrag:kb:owner:{kbId} 2. 如果命中拿到 ownerUserId 3. 判断 ownerUserId 是否等于当前 userId 4. 如果未命中查询 MySQL 5. MySQL 查到后写入 Redis 6. 再进行 owner 判断这样第一次访问会查数据库后续访问可以直接命中 Redis。缓存失效缓存不是数据库不能只写不删。当知识库被删除、状态变化或 owner 发生变化时需要删除对应缓存。否则可能出现MySQL 中知识库已删除 Redis 中 owner 仍然存在 系统误以为资源还能访问缓存不是安全边界这里要强调一点Redis 缓存只是加速 owner 判断不是权限本身。真正的权限依据仍然是数据库中的资源归属。如果缓存未命中就回源 MySQL。如果缓存异常也应该能回退到数据库校验而不是直接放行。05 文档、索引任务和问答中的隔离知识库 owner 校验不是只在知识库接口里用。它贯穿文档、索引任务和问答链路。文档上传用户上传文档时必须先校验当前用户是否拥有这个 kbId只有校验通过系统才会继续上传文件到 MinIO 写入 document_info 创建 index_task 发送 RabbitMQ 消息如果不做这个校验用户就可能往别人的知识库上传文档。文档列表查询文档列表时也要先校验知识库归属。用户只能查看自己知识库下的文档。向量检索向量检索时不能只按问题相似度查 TopK。必须加上范围过滤user_id 当前用户ID kb_id 当前知识库ID否则可能出现严重问题用户提问时检索到了别人知识库里的片段。这比普通接口越权更隐蔽因为用户可能不会直接看到文档列表却会在答案里看到不该看到的信息。RAG 系统不能只相信相似度排序必须先限制检索范围。RAG 问答问答链路也要先校验知识库归属。流程大致是用户提问 - 校验 kb owner - 问题向量化 - 按 userId 和 kbId 检索 - 拼接 Prompt - 调用模型 - 写 qa_log - 返回答案和引用来源qa_log 中也应该记录 userId 和 kbId方便后续管理端查询和问题排查。索引任务索引任务也要带上 userId、kbId、documentId。这样管理员能看到全局任务普通用户只能看到自己文档对应的任务。RabbitMQ 消息中也应该包含这些 ID便于 task-service 消费时校验和更新状态。06 基础后台管理端KnowHub 不只有用户端还有基础后台管理端。管理端的目标不是做一个复杂企业后台而是提供运维视角让管理员能看见系统运行情况。USER 和 ADMIN当前基础角色包括USER ADMIN普通用户登录后只能访问用户端。管理员登录后可以访问管理端。角色信息会写入 JWTGateway 根据角色拦截 /admin/**。管理端能做什么基础管理端通常包含这些能力查看用户列表。修改用户状态。修改用户角色。查看全部知识库。查看全部文档。查看索引任务。筛选失败任务。手动重试失败任务。查看问答日志。这些功能对排查问题很重要。比如用户说“我的文档一直不能问答”管理员可以查看文档是否上传成功 索引任务是否 SUCCESS 失败原因是什么 RabbitMQ 消息是否消费 MinIO 文件是否存在 qa_log 中是否有模型失败记录Gateway 管理员拦截管理端接口必须走 /admin/**。Gateway 看到这个路径后会检查 Token 中的 role。如果不是 ADMIN直接拒绝。这比只在前端隐藏菜单更可靠。管理端前端不是安全边界前端可以做角色判断提高体验。比如普通用户登录管理端时前端提示当前账号不是管理员但真正的安全边界在后端。因为用户可以绕过前端直接调用接口。所以 /admin/** 必须由 Gateway 和后端接口共同保护。07 为什么当前不是完整 RBACKnowHub 当前使用的是基础角色模型。也就是USER ADMIN这已经能满足学习项目中的用户端和管理端隔离。但它不是完整 RBAC。完整 RBAC 通常还包括用户表。角色表。权限表。用户角色关系表。角色权限关系表。菜单权限。按钮权限。数据权限。操作审计。比如一个完整企业后台可能有这些角色超级管理员 知识库管理员 审计员 普通用户 只读用户不同角色能访问不同菜单、不同接口、不同数据范围。KnowHub 当前没有把 RBAC 做到这个复杂度是有意取舍。原因是本系列主线是 AI 知识库 / RAG 平台不是权限系统教程。我们先用 USER / ADMIN 建立清晰边界后续可以把完整 RBAC 作为企业化扩展。08 常见问题排查UserContext 为空现象访问知识库接口时提示未登录或用户上下文不存在。排查顺序前端是否携带 Authorization。请求是否经过 Gateway。Gateway 是否写入X-User-Id。knowledge-service 是否配置 UserContextInterceptor。请求头名称是否一致。A 用户能看到 B 用户数据这是严重问题。排查顺序查询接口是否带了user_id条件。详情接口是否校验 owner。文档接口是否先校验 kb owner。向量检索是否按 userId/kbId 过滤。管理端接口是否误暴露给普通用户。Redis owner 缓存脏数据现象数据库中知识库已经删除或变更但接口仍然认为它存在。排查删除知识库时是否删除rag:kb:owner:{kbId}。缓存 TTL 是否过长。是否有回源 MySQL 校验。Redis 中的 value 是否和数据库一致。普通用户访问管理接口普通用户访问 /admin/** 返回 403 是正常的。如果普通用户能访问成功要检查Token 中 role 是否错误。Gateway 是否启用了 admin 路径校验。路径是否没有以/admin/开头。后端管理接口是否绕过了 Gateway。管理员登录后仍然无权限排查顺序数据库中用户 role 是否为 ADMIN。登录后新签发的 Token 是否包含 ADMIN。前端是否仍使用旧 Token。Gateway 是否正确解析 role。role 大小写是否一致。向量检索返回了疑似他人知识库的内容这是 RAG 系统里很隐蔽也很严重的问题。排查顺序向量检索 SQL 是否带了 userId 过滤条件。userId 是否从 UserContext 获取而不是从请求参数获取。pgvector 向量记录是否包含 userId 字段。task-service 写入向量时是否正确设置 userId。查询条件正确但仍异常时再检查 pgvector 索引和查询执行计划。09 动手验证用户资源隔离是否生效第一步注册两个用户 A 和 B分别登录获取各自的 Token。POST http://localhost:8080/auth/register Body: {”username”:”userA”,”password”:”123456”,”nickname”:”用户A”}POST http://localhost:8080/auth/login Body: {”username”:”userA”,”password”:”123456”} 预期结果返回用户 A 的 Token同样方式注册并登录用户 B。第二步用户 A 创建一个知识库记下 kbId。POST http://localhost:8080/kb Authorization: Bearer 用户A的Token Body: {”name”:”A的知识库”,”description”:”资源隔离验证”} 预期结果创建成功返回 kbId第三步用户 B 访问用户 A 的知识库。GET http://localhost:8080/kb/{用户A的kbId} Authorization: Bearer 用户B的Token 预期结果返回“知识库不存在”或类似错误第四步用户 B 往用户 A 的知识库上传文件。POST http://localhost:8080/kb/{用户A的kbId}/documents/upload Authorization: Bearer 用户B的Token Body: form-datafile任意 txt/pdf 文件 预期结果返回错误不能上传成功第五步用户 A 访问自己的知识库。GET http://localhost:8080/kb/{用户A的kbId} Authorization: Bearer 用户A的Token 预期结果正常返回知识库详情第六步普通用户 A 访问管理端索引任务。GET http://localhost:8080/admin/index-tasks Authorization: Bearer 用户A的Token 预期结果返回 403如果某一步不符合预期先确认 Gateway 是否正常透传了 X-User-Id再确认当前登录用户的 userId 是否和知识库的 user_id 对应然后逐步排查 Service 查询条件、Redis owner 缓存、MySQL 数据和 Gateway 管理员路径校验。本章小结这一章我们讲清楚了 KnowHub 的用户资源隔离和基础后台管理设计。登录认证只能证明用户是谁不能代表用户能访问所有资源。真正的资源边界必须在业务服务中校验。知识库是 KnowHub 的核心资源因此 knowledge_base.user_id 是用户隔离的基础。用户创建知识库时owner 来自当前登录用户用户查询、上传文档、发起问答时都必须校验知识库归属。为了减少高频 owner 校验带来的数据库访问系统使用 Redis 缓存 rag:kb:owner:{kbId}但缓存只是加速手段不能替代数据库中的权限依据。管理端基于 USER / ADMIN 做基础角色隔离。Gateway 负责拦截 /admin/**管理端接口负责提供用户、知识库、文档、索引任务和问答日志的运维视角。下一章我们将进入知识库管理与文档元数据开始讲用户真正操作的第一个业务核心创建知识库、上传文档以及如何把文件记录成可追踪的数据。作者有话说如果这篇文章对你有帮助欢迎点个关注。这个专栏会持续更新KnowHub / RAG 平台实战内容后面会继续把知识库管理、文档元数据、文件存储、文档解析和索引任务拆开讲清楚。如果你想对照代码学习可以结合下面两个仓库rag-demo-monolith单体版源码适合先理解 RAG 核心闭环把业务链路跑通。仓库地址https://gitee.com/MrLuoBin/rag-demo-monolith.githttps://github.com/luobinsnbb/rag-demo-monolith.git克隆命令git clone https://gitee.com/MrLuoBin/rag-demo-monolith.gitrag-platform微服务版源码适合继续学习 Gateway、Auth、Knowledge、Task 的企业级拆分方式。仓库地址https://gitee.com/MrLuoBin/rag-platform.git克隆命令git clone https://gitee.com/MrLuoBin/rag-platform.git如果你在做 AI 知识库或 RAG 项目建议把“用户能访问什么资源”作为第一优先级设计。RAG 系统一旦发生检索越权风险比普通接口越权更隐蔽。学AI大模型的正确顺序千万不要搞错了2026年AI风口已来各行各业的AI渗透肉眼可见超多公司要么转型做AI相关产品要么高薪挖AI技术人才机遇直接摆在眼前有往AI方向发展或者本身有后端编程基础的朋友直接冲AI大模型应用开发转岗超合适就算暂时不打算转岗了解大模型、RAG、Prompt、Agent这些热门概念能上手做简单项目也绝对是求职加分王给大家整理了超全最新的AI大模型应用开发学习清单和资料手把手帮你快速入门学习路线:✅大模型基础认知—大模型核心原理、发展历程、主流模型GPT、文心一言等特点解析✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑✅开发基础能力—Python进阶、API接口调用、大模型开发框架LangChain等实操✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经以上6大模块看似清晰好上手实则每个部分都有扎实的核心内容需要吃透我把大模型的学习全流程已经整理好了抓住AI时代风口轻松解锁职业新可能希望大家都能把握机遇实现薪资/职业跃迁这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】