# OAuth 登录优化总结 ## 完成的优化 ### 1. 修复 React StrictMode 重复调用问题 ✅ **问题**: - OAuth 回调组件在开发环境下被调用两次 - 导致授权码被使用两次,第二次调用失败 **解决方案**: - 使用 `useRef` 替代 `useState` 来跟踪处理状态 - 移除 `isProcessing` 从 `useEffect` 依赖数组 - 添加日志以便调试 **修改文件**: - `web/apps/lq_label/src/components/oauth-callback/oauth-callback.tsx` **关键代码**: ```typescript const isProcessingRef = useRef(false); useEffect(() => { if (isProcessingRef.current) { console.log('Already processing, skipping duplicate call'); return; } const processCallback = async () => { isProcessingRef.current = true; // ... 处理逻辑 }; processCallback(); }, [searchParams, navigate, setAuth]); // 不包含 isProcessing ``` ### 2. 优化 401 错误处理 ✅ **改进**: - 所有 401 错误都会自动跳转到登录页面 - 区分 token 过期和其他认证失败 - 清除本地存储的认证数据 - 显示友好的错误提示 **修改文件**: - `web/apps/lq_label/src/services/api.ts` **处理逻辑**: 1. **Token 过期**(`error_type === 'token_expired'`): - 尝试使用 refresh token 刷新 - 刷新成功:重试原请求 - 刷新失败:清除数据,跳转登录页 2. **其他 401 错误**(无效凭证等): - 直接清除认证数据 - 显示"认证失败,请重新登录" - 跳转到登录页面 ### 3. 优化登录界面设计 ✅ **设计改进**: - ❌ 移除渐变色背景 - ✅ 使用设计令牌(Design Tokens) - ✅ 登录表单放在右侧 1/3 - ✅ 左侧 2/3 显示品牌信息和特性 - ✅ 添加背景图案增强视觉效果 - ✅ 添加功能特性卡片 - ✅ 优化按钮交互效果 - ✅ 响应式设计(移动端自适应) **修改文件**: - `web/apps/lq_label/src/components/login-form/login-form.tsx` - `web/apps/lq_label/src/components/login-form/login-form.module.scss` **新设计特点**: 1. **左侧品牌区域**: - 大号品牌 Logo(120x120px) - 品牌名称和描述 - 背景几何图案(低透明度) - 4 个功能特性卡片: * 高效标注 * 团队协作 * 实时同步 * 安全可靠 2. **右侧登录区域**: - 清晰的标题"欢迎回来" - SSO 登录按钮(悬停效果) - 分隔线"或使用账号密码" - 用户名和密码输入框 - 登录按钮(阴影和悬停效果) - 注册链接 3. **视觉细节**: - Logo 带有光晕效果 - 按钮悬停时有平滑过渡 - 输入框聚焦时有边框高亮 - 卡片式布局,层次分明 - 使用阴影增强深度感 **新布局**: ``` ┌─────────────────────────────────────────────────────────────┐ │ │ │ │ [背景图案] │ 欢迎回来 │ │ │ 登录您的账号以继续使用标注平台 │ │ [标 Logo] │ │ │ 标注平台 │ [使用 SSO 登录] │ │ 高效、智能的数据标注... │ │ │ │ ─── 或使用账号密码 ─── │ │ ┌────┬────┐ │ │ │ │高效│团队│ │ 用户名: [____________] │ │ │标注│协作│ │ 密码: [____________] │ │ ├────┼────┤ │ │ │ │实时│安全│ │ [登录] │ │ │同步│可靠│ │ │ │ └────┴────┘ │ 还没有账号?立即注册 │ │ │ │ └─────────────────────────────────────────────────────────────┘ 左侧 (2/3) 右侧 (1/3) ``` ## 测试建议 ### 1. 测试 OAuth 重复调用修复 1. 打开浏览器开发者工具(Console 标签) 2. 访问 `http://localhost:4200/login` 3. 点击"使用 SSO 登录" 4. 完成 OAuth 登录 5. 检查控制台日志: - 应该只看到一次 "Starting OAuth callback processing..." - 如果看到 "Already processing, skipping duplicate call",说明修复生效 ### 2. 测试 401 错误处理 **测试 Token 过期**: 1. 登录系统 2. 等待 15 分钟(access token 过期) 3. 执行任何 API 操作 4. 应该自动刷新 token 并继续操作 **测试无效 Token**: 1. 登录系统 2. 手动修改 localStorage 中的 access_token 3. 执行任何 API 操作 4. 应该显示"认证失败,请重新登录"并跳转到登录页 ### 3. 测试登录界面 **桌面端**: 1. 访问 `http://localhost:4200/login` 2. 检查布局: - 左侧显示品牌信息(占 2/3) - 右侧显示登录表单(占 1/3) - 无渐变色背景 - 使用设计令牌颜色 **移动端**: 1. 调整浏览器窗口宽度 < 768px 2. 检查布局: - 品牌信息在上方 - 登录表单在下方 - 垂直排列 ## 配置文件 ### OAuth 配置(`backend/config.yaml`) ```yaml oauth: enabled: true base_url: "http://192.168.92.61:8000" client_id: "sRyfcQwNVoFimigzuuZxhqd36fPkVN5G" client_secret: "96RuKb4obAn9bQ9i5NtINiKBMvF_9uuCR7eNzD9dWQMbOWZaV3P593-8yLOqzWRd" redirect_uri: "http://localhost:4200/auth/callback" scope: "profile email" authorize_endpoint: "/oauth/login" token_endpoint: "/oauth/token" userinfo_endpoint: "/oauth/userinfo" ``` ## 相关文档 - [OAuth 登录测试指南](./OAUTH_LOGIN_TEST_GUIDE.md) - [OAuth 集成指南](./OAUTH_INTEGRATION_GUIDE.md) - [前端认证指南](./web/apps/lq_label/FRONTEND_AUTH_GUIDE.md) - [后端 JWT 认证指南](./backend/JWT_AUTHENTICATION_GUIDE.md) ## 技术栈 - **前端**:React 18, TypeScript, Jotai, React Router - **后端**:FastAPI, Python, SQLAlchemy - **认证**:JWT, OAuth 2.0 - **样式**:SCSS Modules, Design Tokens ## 下一步 1. ✅ 修复 React StrictMode 重复调用 2. ✅ 优化 401 错误处理 3. ✅ 优化登录界面设计 4. 🔄 测试完整的 OAuth 登录流程 5. 🔄 验证用户同步到本地数据库 6. 🔄 测试 token 刷新机制 --- **更新日期**: 2024-01-22 **状态**: ✅ 完成 **版本**: 1.0