fix: 系统性修复多用户数据隔离问题#474
Merged
Merged
Conversation
- Replace fetch() with apiFetch() in 18 files across web/ - Remove redundant credentials: 'include' since apiFetch handles it - Affected modules: auth, admin, session, skills, book, knowledge, notebook, co-writer, playground, agents, sidebar components, SaveToNotebookModal, VersionBadge, useTextSource - Fixes 401 Unauthorized errors in multi-user mode
核心修改: - BaseSessionManager: path_service/sessions_file 改为 @Property 延迟解析 - chat.py/solve.py: 移除模块级单例,WebSocket 端点添加手动认证 - BookStorage/BookEngine: path_service 延迟解析 + get_book_storage/engine 按路径缓存 - TutorBotManager: path_service 延迟解析 + 修复硬编码 data/tutorbot 路径 - MemoryService: _path_service 改为 @Property 延迟解析 修复原理:延迟解析确保路径在请求时(用户上下文已设置)才解析; 按路径缓存确保不同用户获得不同实例,同一用户复用实例。 TutorBot 现在按用户隔离到 multi-user/<uid>/tutorbot/ 而非共享的 data/tutorbot/
核心问题: 1. HTTP请求的用户上下文仅依赖require_auth依赖,中间件层无保障 2. WebSocket端点(tutorbot/vision_solver/question/knowledge/book)缺少手动认证 3. CoWriterStorage在__init__中固定path_service,单例后路径不再变化 4. get_path_service()静默降级到默认实例,无日志 修复内容: - 添加user_context_middleware中间件,确保每个HTTP请求都正确设置用户ContextVar - 添加ws_require_auth()统一WebSocket认证函数,所有WS端点使用 - 修复tutorbot/vision_solver/question/knowledge/book的WebSocket认证 - 统一chat/solve/unified_ws的WebSocket认证为ws_require_auth() - CoWriterStorage改为@Property延迟获取path_service + 按workspace缓存 - get_path_service()降级时输出warning日志
…ddleware
After rebasing onto current dev (v1.3.10), several issues surfaced that the
original PR did not account for:
Frontend (rebase regressions from older PR base):
- web/lib/knowledge-api.ts: restore 6 KnowledgeBaseSummary fields
(id, source, assigned, read_only, provenance_label, available) that the
multi-user knowledge feature added between the PR base and current dev.
- web/app/(workspace)/agents/page.tsx: restore the array-vs-{bots}
response shape fallback; the tutorbot list endpoint returns either form.
- web/components/sidebar/BookRecent.tsx: wrap path with apiUrl() — the
apiFetch swap accidentally dropped the wrapper.
- web/components/space/MemorySection.tsx: restore try/catch error toasts
in loadMemory and clearMemory (still present in saveMemory and
refreshMemory; were dropped in load/clear).
Backend (decouple auth from middleware):
- Remove user_context_middleware from api/main.py. It was redundant with
require_auth (sets the user ContextVar for every protected route) and
ws_require_auth (sets it for every WebSocket). When AUTH_ENABLED=true and
a request had no valid token, the middleware fell back to
local_admin_user() — harmless because require_auth then raised 401, but
a latent footgun if any code reads the ContextVar before the dependency
resolves. Removing it makes the auth flow single-pathed and removes the
"ctx set twice" pattern.
- auth.py: add explicit type annotations to ws_require_auth (returns
Token | _WsAuthFailed) and the ws_auth_failed sentinel.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
pancacake
pushed a commit
to wedone/DeepTutor
that referenced
this pull request
May 12, 2026
deleteMessage was the one remaining raw fetch() call in session-api.ts. After PR HKUDS#474 wired multi-user auth through apiFetch (which attaches the JWT bearer token from local storage / cookies), this call would fail with 401 Unauthorized in multi-user mode. Switch to apiFetch to match the convention established for every other authenticated session call in this file. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
8 tasks
kagura-agent
pushed a commit
to kagura-agent/DeepTutor
that referenced
this pull request
May 21, 2026
deleteMessage was the one remaining raw fetch() call in session-api.ts. After PR HKUDS#474 wired multi-user auth through apiFetch (which attaches the JWT bearer token from local storage / cookies), this call would fail with 401 Unauthorized in multi-user mode. Switch to apiFetch to match the convention established for every other authenticated session call in this file. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
多用户数据隔离系统性修复
本 PR 系统性修复了 DeepTutor 多用户模式下的数据隔离问题,确保不同用户的数据完全隔离,避免跨用户数据泄露和路径混淆。
核心问题
require_auth依赖,中间件层无保障CoWriterStorage在__init__中固定path_service,单例后路径不再变化get_path_service()静默降级到默认实例,无日志输出fetch()而非apiFetch(),导致多用户模式下 401 错误修复内容
后端修复
user_context_middleware中间件,确保每个 HTTP 请求都正确设置用户ContextVarws_require_auth()统一 WebSocket 认证函数,所有 WS 端点使用ws_require_auth()CoWriterStorage改为@property延迟获取path_service+ 按 workspace 缓存BaseSessionManager:path_service/sessions_file改为@property延迟解析BookStorage/BookEngine:path_service延迟解析 +get_book_storage/engine按路径缓存TutorBotManager:path_service延迟解析 + 修复硬编码data/tutorbot路径MemoryService:_path_service改为@property延迟解析get_path_service()降级时输出 warning 日志前端修复
fetch()为apiFetch(),确保携带认证信息credentials: 'include'(apiFetch已处理)架构改进
延迟解析模式:路径在请求时(用户上下文已设置)才解析,而非模块加载时
按路径缓存:不同用户获得不同实例,同一用户复用实例,兼顾隔离和性能
测试验证
multi-user/<uid>/tutorbot/而非共享的data/tutorbot/Related Issues
Module(s) Affected
apiservicesweb(Frontend)multi-user,book,co-writer,memory,tutorbotChecklist
pre-commit run --all-filesand fixed any issues. (ruff/ruff-format/prettier passed; mypy/bandit failures are pre-existing upstream issues)Additional Notes
分支基准: 本 PR 基于
v1.3.8开发,包含 3 个修复提交:429ab6b230dfe56d5f187