refactor: session token isolation with OOP context redesign#50
Merged
Conversation
主要改进:
- 新增 tokenResolver 模块
- resolveToken(): 按需解析 Token(无全局状态)
- getUserId(): 提取用户标识
- hasToken(): 检查 Token 可用性
- 支持用户 + 项目双重隔离
- 改造 tokenStorage 支持用户隔离
- getTokenPath(): 支持 userId 和 projectId 参数
- saveToken(): 保存到用户隔离目录
- clearToken(): 清除用户隔离的 token
- 路径格式:{cacheDir}/{userId}/{projectId?}/oauth-token.json
设计原则:
- 无全局状态:每次请求动态解析
- 用户隔离:不同用户 token 完全隔离
- 项目隔离:同一用户的不同项目可选隔离
目录结构:
- stdio 模式:~/.taptap-mcp/cache/local/oauth-token.json
- Proxy 模式:~/.taptap-mcp/cache/{userId}/oauth-token.json
- 项目隔离:~/.taptap-mcp/cache/{userId}/{projectId}/oauth-token.json
为 Session Token 隔离修复打下基础。
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
主要改进: - 新增 extractPrivateParamsFromHeaders() 方法 - 规范化 Header 提取逻辑 - 支持 _mac_token、_user_id、_project_id 提取 - 处理大小写和数组值 - 扩展 CORS 支持 - 添加 X-TapTap-User-Id Header - 添加 X-TapTap-Project-Id Header - 允许 IDE 在连接时传递用户和项目标识 - 统一私有参数注入机制 - MCP Proxy: 通过 args 注入 - HTTP/SSE: 通过 Headers 注入 - 优先级:args > headers 设计原则: - IDE 友好:只需配置一次 Headers - 类型安全:规范化处理避免运行时错误 - 向后兼容:不影响现有 Proxy 模式 为 Session 闭包注入打下基础。 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
主要改进: - 移除 ApiConfig 的全局 Token 管理 - 删除 ApiConfig.macToken 字段 - 删除 ApiConfig.setMacToken() 方法 - 删除 ApiConfig.isConfigured() 方法 - ApiConfig 现在只负责启动时配置验证 - HttpClient 改用 tokenResolver - 构造函数保存 context(包含 userId/projectId) - request() 调用 resolveToken(context) 动态解析 - 每次请求根据用户标识加载对应 token - handlerHelpers 改用 tokenResolver - getEffectiveMacToken() 使用 resolveToken() - getMacTokenStatus() 使用 resolveToken() - 不再依赖全局 ApiConfig.macToken - server.ts 移除全局 token 操作 - createBaseContext() 不再读取全局 token - ensureAuthenticated() 不再预加载 token - main() 不再检查全局 token 状态 - handlers.ts 移除全局 token 操作 - completeOAuthAuthorization() 不再设置全局 - clearAuthData() 不再清除全局 架构改进: - ✅ 完全无状态:每次请求动态解析 - ✅ Session 隔离:不同 session 完全隔离 - ✅ 用户隔离:不同用户 token 分别存储 - ✅ 性能可控:文件读取 <1ms 安全修复: - ✅ 消除跨 session token 泄露风险 - ✅ 消除跨用户 token 共享问题 - ✅ 符合 HTTP 服务器无状态设计原则 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
主要改进: - 在 HandlerContext 中添加 projectId 字段 - 用于 Token 项目级隔离 - 与 projectPath 共存(不同用途) 字段说明: - projectId: 项目标识符(用于 Token 隔离) - projectPath: 项目文件路径(用于文件系统访问) 支持场景: - MCP Proxy: 可注入 projectId - SSE 模式: 可通过 X-TapTap-Project-Id Header 传递 - stdio 模式: 可选,用于多项目管理 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
主要改进: - contextResolver 改为纯函数设计 - ContextResolver 类 → resolveAppContext() 等函数 - 新增 getUserId() 和 getProjectId()(从 tokenResolver 移入) - 统一的函数式 API,更易用 - tokenResolver 增强 - 新增 getTokenStatus()(从 handlerHelpers 移入) - 新增 getTokenSourceLabel() - 新增 TokenSource enum - 统一 Token 相关的所有工具函数 - handlerHelpers 精简 - 移除重复的 Token 状态函数(已移至 tokenResolver) - 保留参数合并相关函数(getEffectiveContext 等) - 通过 re-export 保持向后兼容 - server.ts 清理 - 移除未使用的 import - 移除废弃的 setTransportMode - 使用 tokenResolver.hasToken() 检查认证 架构优化: - ✅ 设计模式统一(都是纯函数) - ✅ 职责清晰分层 - contextResolver: Context 字段解析 - tokenResolver: Token 加载和状态 - handlerHelpers: 参数合并工具 - ✅ 减少代码重复(净减少 38 行) - ✅ 易于测试和维护 向后兼容: - handlerHelpers 通过 re-export 保持兼容 - 所有现有代码正常工作 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
主要改进: - OAuth 完成后返回简洁消息 - 移除技术细节(userId、projectId、文件路径) - 移除模式说明(stdio/SSE) - 移除 Header 配置说明 设计原则: - ✅ 对 AI Agent 透明:不暴露底层实现细节 - ✅ 只告诉 AI 结果:授权成功,可以继续操作 - ✅ 技术细节在日志中:stderr 仍然输出完整路径 AI Agent 视角: - "授权完成" → 知道可以继续 - 不需要知道 userId/projectId - 不需要知道 stdio/SSE 模式 - 不需要配置 Header(由 IDE/Proxy 处理) 人类开发者视角: - stderr 日志显示完整路径 - 调试时可以看到技术细节 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
主要改进: - 新增 types/context.ts(Context 专属模块) - RequestContext: 请求原始上下文(接口) - AppContext: 应用信息解析结果(接口) - SessionContext: Session 上下文(接口) - ResolvedContext: 运行时 Context 类 - TokenSource: Token 来源枚举 - ResolvedContext 类设计 - 构造器:合并 args + baseContext(替代 getEffectiveContext) - 字段访问:userId, projectId, developerId 等(getter) - resolveApp(): 解析应用信息(含缓存) - resolveToken(): 解析 MAC Token(用户隔离) - hasToken/hasApp/getTokenStatus 等便捷方法 - 无缓存设计 - 每次调用方法都重新计算/加载 - 外部决定是否缓存结果 - 避免状态不一致性 - types/index.ts 简化 - 移除 HandlerContext 定义(已移至 context.ts) - 导出 context.ts 的所有类型 - 保留 HandlerContext 别名(向后兼容) - 更新 ToolRegistration - handler 签名改为接受 ResolvedContext 架构优化: - ✅ 职责内聚:Context 相关逻辑在一个文件 - ✅ 请求级生命周期:用完即丢 - ✅ 面向对象:更自然的 API 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
主要改进: - server.ts 使用 ResolvedContext - createBaseContext() 返回 RequestContext - 构建 ResolvedContext 传递给 handler - ensureAuthenticated() 接受 ResolvedContext - 使用 ctx.hasToken() 检查认证 - 简化认证检查逻辑 - 不再需要 import tokenResolver - 直接调用 ctx.hasToken() 下一步:批量更新所有 handlers 签名 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
主要改进: - 批量更新 3 个 handlers 文件(15+ 函数) - app/handlers.ts: 7 个函数 - leaderboard/handlers.ts: 5 个函数 - h5Game/handlers.ts: 4 个函数 - 签名统一 - context: HandlerContext → ctx: ResolvedContext - 所有函数体内变量名改为 ctx - API 调用现代化 - getUserId(context) → ctx.userId - getProjectId(context) → ctx.projectId - resolveToken(context) → ctx.resolveToken() - getTokenStatus(context) → ctx.getTokenStatus() - resolveAppContext(context) → ctx.resolveApp() - 正确传递 context - 需要 RequestContext 的地方用 ctx.raw - getAllDevelopersAndApps(ctx.raw) - new HttpClient(ctx.raw) - 清理 imports - 移除 getUserId/getProjectId 等 resolver 导入 - 移除 getTokenStatus/getTokenSourceLabel 导入 代码改进: - ✅ API 更简洁:ctx.xxx vs getXxx(context) - ✅ 类型安全:ResolvedContext 提供完整方法 - ✅ 易于理解:面向对象的 API 测试结果: - ✅ 48/48 测试通过 - ✅ 编译成功 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
…ntext 主要改进: - 删除旧的 resolver 文件 - contextResolver.ts(已集成到 ResolvedContext 类) - tokenResolver.ts(已集成到 ResolvedContext 类) - handlerHelpers.ts(已集成到 ResolvedContext 类) - 更新 HttpClient - 移除 resolveToken() 调用 - 内联 token 解析逻辑 - 直接从 context 或文件加载 - 更新 leaderboard/api.ts - 移除 resolveAppContext() 调用 - 内联应用信息解析逻辑 - 直接从 context 和 cache 读取 代码简化: - ✅ 删除 3 个文件(~400 行) - ✅ 统一使用 ResolvedContext - ✅ 减少模块依赖 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
主要改进: - 抽象 Token 解析逻辑 - 新增私有方法 resolveTokenWithSource() - 统一处理 token 解析和来源识别 - 消除代码重复 - 三个公开方法复用同一逻辑 - resolveToken(): 只返回 token - hasToken(): 检查 token 有效性 - getTokenStatus(): 返回 token + 来源 代码优化: - ✅ DRY 原则:单一数据源 - ✅ 性能优化:getTokenStatus() 不会重复解析 - ✅ 易于维护:逻辑集中在一个方法 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
主要改进: - HttpClient 使用 ResolvedContext.resolveToken() - 移除重复的 token 解析逻辑 - 统一使用 ResolvedContext 的方法 - 代码从 13 行简化为 3 行 实现: - 在 request() 中动态创建 ResolvedContext - 调用 ctx.resolveToken() 获取 token - 复用 ResolvedContext 的完整逻辑 优点: - ✅ 消除代码重复 - ✅ 逻辑集中在 ResolvedContext - ✅ 易于维护 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1e2954c to
8f12563
Compare
主要改进: - API 层全部改为接受 ResolvedContext - app/api.ts: 10 个函数 - leaderboard/api.ts: 3 个函数 - h5Game/api.ts: 1 个函数 - 统一函数签名 - context?: HandlerContext → ctx: ResolvedContext - 所有变量名 context → ctx - 直接传递给 HttpClient(ctx) - 移除旧的 resolver 调用 - resolveAppContext(ctx) → ctx.resolveApp() - context?.projectPath → ctx?.projectPath 架构原则: - ✅ ResolvedContext 只在 server.ts 构建 - ✅ API 层只接受和传递(不重新构建) - ✅ 全链路传递同一个实例 测试结果: - ✅ 28/28 测试通过 - ✅ 编译成功 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
8615ce3 to
8dd9c01
Compare
主要修复: - 移除所有 ctx.raw 错误调用 - handlers 直接传递 ctx(不是 ctx.raw) - API 层接受 ctx 并继续传递 - 更新 h5Game/handlers.ts - context?: RequestContext → ctx?: ResolvedContext - 所有变量名 context → ctx - 传递 ctx 给 API 函数 - 清理 server.ts - 移除未使用的 loadToken 导入 架构验证: - ✅ server.ts: 唯一构建点 - ✅ handlers: 接受并传递 ctx - ✅ API: 接受并传递 ctx - ✅ HttpClient: 使用 ctx.resolveToken() - ✅ 全链路传递同一个 ResolvedContext 实例 测试结果: - ✅ 28/28 测试通过 - ✅ 编译成功 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
f13956b to
19bf74f
Compare
主要改进: - 抽象 printServerInfo() 方法 - 统一 stdio 和 SSE 模式的启动日志 - 消除重复代码(~60 行重复) - 增强启动日志(所有模式) - 显示 Client ID 和 Client Secret 状态 - 显示 3 个目录配置(WORKSPACE_ROOT, CACHE_DIR, TEMP_DIR) - 修复 SSE 模式 token 加载 - 所有模式都支持从文件加载 token - 移除 stdio 专属限制 代码优化: - ✅ DRY 原则:统一的日志打印 - ✅ 易于维护:修改一处即可 - ✅ 信息完整:显示所有关键配置 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
fc2cc22 to
2341413
Compare
MikotoZero
commented
Nov 24, 2025
MikotoZero
left a comment
Collaborator
Author
There was a problem hiding this comment.
@copilot review 使用中文描述
|
@MikotoZero I've opened a new pull request, #51, to work on those changes. Once the pull request is ready, I'll request review from you. |
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.
🔐 安全修复 + 架构重构
本 PR 实现了 Session Token 隔离并重构为面向对象的 Context 架构。
🎯 核心改进
1. Session Token 隔离(安全修复)
问题: 旧版
ApiConfig.macToken是全局单例,SSE 模式下多个 session 共享同一个 token风险: User A 的 token 可能被 User B 使用,存在安全隐患
解决方案:
~/.taptap-mcp/cache/{userId}/{projectId}/oauth-token.jsonX-TapTap-User-Id,X-TapTap-Project-Id2. ResolvedContext 架构(OOP 重构)
问题: 函数式 Resolver 分散在多个文件,API 冗长
旧代码:
新代码:
改进:
types/context.ts专门管理 Context📊 改进成果
🔒 安全问题解决
{userId}/{projectId}路径🏗️ 架构优化
类型层次
设计原则
_raw不可修改🧪 测试验证
📋 使用示例
IDE 配置(SSE 模式)
{ "mcpServers": { "taptap": { "url": "http://localhost:3000", "headers": { "X-TapTap-User-Id": "my-account", "X-TapTap-Project-Id": "my-project" } } } }Handler 代码
🚀 版本影响
1.6.0(minor)🤖 Generated with Claude Code