Files
newToy/HASH_MODE_SPOTIFY_SOLUTION.md
2025-11-23 23:55:10 +08:00

3.8 KiB
Raw Permalink Blame History

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

// 使用根路径作为 redirect_uri
const REDIRECT_URI = window.location.origin + '/'

Home.vue

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

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. 部署新代码

    # 代码已构建完成
    rsync -avz --delete dist/ user@sports.rucky.cn:/var/www/sports.rucky.cn/
    
  3. 清除缓存测试

    localStorage.clear()
    sessionStorage.clear()
    

🧪 测试流程

  1. 访问 https://sports.rucky.cn/
  2. 进入音乐律动页面 (#/music-rhythm)
  3. 点击 Spotify 标签
  4. 点击"连接 Spotify 账号"
  5. 在 Spotify 页面授权
  6. 应该看到:
    • 返回到首页(带 code 参数)
    • 自动跳转到 #/callback
    • 显示"正在处理授权..."
    • 显示"授权成功!"
    • 自动跳转回音乐律动页面
    • Spotify 功能正常使用

🔍 调试

如果有问题,检查浏览器控制台:

// 应该看到以下日志:
"✅ 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 回调
  • 完整的授权流程
  • 良好的用户体验

现在部署新代码,就能完美使用了!🎉