# ✅ Hash 模式下的 Spotify OAuth 完美解决方案 ## 🎯 最终方案 ### 1. Spotify Dashboard 配置 **Redirect URIs:** ``` https://sports.rucky.cn/ (生产环境) http://localhost:5173/ (开发环境) ``` ⚠️ **重要:不要使用 hash 格式!** - ❌ `https://sports.rucky.cn/#/callback` - ✅ `https://sports.rucky.cn/` ### 2. 工作流程 ``` 用户点击"连接 Spotify 账号" ↓ 跳转到 Spotify (redirect_uri=https://sports.rucky.cn/) ↓ 用户授权 ↓ Spotify 返回: https://sports.rucky.cn/?code=xxx&state=xxx ↓ Home.vue 检测到 code 参数 ↓ 保存参数到 sessionStorage ↓ 跳转到 #/callback 路由 ↓ SpotifyCallback.vue 处理授权 ↓ 授权成功,跳转到音乐律动页面 ``` ### 3. 关键代码 **MusicRhythm.vue:** ```typescript // 使用根路径作为 redirect_uri const REDIRECT_URI = window.location.origin + '/' ``` **Home.vue:** ```typescript onMounted(() => { // 检测 Spotify 回调 const urlParams = new URLSearchParams(window.location.search) if (urlParams.has('code') && urlParams.has('state')) { // 保存参数并跳转到 callback 路由 sessionStorage.setItem('spotify_callback_params', window.location.search) router.replace('/callback') } }) ``` **SpotifyCallback.vue:** ```typescript onMounted(async () => { // 从 sessionStorage 恢复参数 const savedParams = sessionStorage.getItem('spotify_callback_params') if (savedParams) { // 恢复 URL 参数供 spotifyService 处理 const currentUrl = new URL(window.location.href) currentUrl.search = savedParams window.history.replaceState({}, '', currentUrl.toString()) // 清理 sessionStorage.removeItem('spotify_callback_params') } // 处理授权 if (window.location.search.includes('code=')) { await spotifyService.handleCallback() } }) ``` ## ✅ 优势 1. **兼容性好** - 支持 Hash 模式路由 - 不需要服务器配置 SPA 支持 2. **用户体验流畅** - 自动检测和处理回调 - 清晰的加载和成功提示 - 自动跳转回原页面 3. **安全可靠** - State 参数验证(CSRF 保护) - 参数临时存储,用后即删 - URL 清理,不暴露敏感信息 ## 📋 部署步骤 1. **修改 Spotify Dashboard** - 删除 `https://sports.rucky.cn/#/callback` - 添加 `https://sports.rucky.cn/` - 保存设置 2. **部署新代码** ```bash # 代码已构建完成 rsync -avz --delete dist/ user@sports.rucky.cn:/var/www/sports.rucky.cn/ ``` 3. **清除缓存测试** ```javascript localStorage.clear() sessionStorage.clear() ``` ## 🧪 测试流程 1. 访问 https://sports.rucky.cn/ 2. 进入音乐律动页面 (#/music-rhythm) 3. 点击 Spotify 标签 4. 点击"连接 Spotify 账号" 5. 在 Spotify 页面授权 6. 应该看到: - ✅ 返回到首页(带 code 参数) - ✅ 自动跳转到 #/callback - ✅ 显示"正在处理授权..." - ✅ 显示"授权成功!" - ✅ 自动跳转回音乐律动页面 - ✅ Spotify 功能正常使用 ## 🔍 调试 如果有问题,检查浏览器控制台: ```javascript // 应该看到以下日志: "✅ Spotify OAuth callback detected!" "Code: AQBTrOWWZ8883ozZ1RD..." "State: RxEHF89uqI2Y0YFR" "✅ Processing Spotify OAuth callback from sessionStorage" ``` ## 📝 注意事项 1. **必须使用根路径** - Spotify 不支持 hash 格式的 redirect_uri - 只能使用 `https://sports.rucky.cn/` 2. **Hash 模式的限制** - URL 会短暂显示 code 参数 - 需要额外的跳转步骤 3. **sessionStorage 的作用** - 临时保存参数 - 跨路由传递数据 - 用后自动清理 ## ✅ 问题已解决 - ✅ 支持 Hash 模式路由 - ✅ 正确处理 Spotify 回调 - ✅ 完整的授权流程 - ✅ 良好的用户体验 现在部署新代码,就能完美使用了!🎉