Files
cstb-next/docs/auth-integration.md
2025-11-05 11:21:13 +08:00

4.5 KiB
Raw Blame History

认证集成说明

概述

本应用已实现与网页端(https://cstb.upup.cool/)的邮箱注册登录功能集成。用户可以通过网页端登录/注册,然后通过 deep-link 回调到本地应用。

实现方案

1. 用户流程

  1. 用户在本地应用中点击"登录"或"注册"按钮
  2. 应用打开浏览器,跳转到网页端登录/注册页面
  3. 用户在网页端完成登录/注册
  4. 网页端重定向到 cstb://auth deep-link携带认证信息
  5. 本地应用接收 deep-link 回调,解析并设置 session
  6. 用户状态同步到本地应用

2. 技术实现

前端Next.js + Tauri

  • 认证 Store (src/store/auth.ts): 管理用户状态和会话
  • 认证工具 (src/utils/auth.ts): 处理登录/注册跳转和回调解析
  • 认证 Provider (src/components/auth/AuthProvider.tsx): 监听 deep-link 和认证状态变化
  • 认证按钮 (src/components/auth/AuthButton.tsx): UI 组件,显示登录状态和用户信息
  • Scheme: cstb
  • 回调 URL 格式: cstb://auth?access_token=xxx&refresh_token=xxxcstb://auth?code=xxx

3. 网页端集成要求

网页端需要在登录/注册成功后,重定向到 deep-link URL。以下是几种实现方式

方式 1: 使用 access_token 和 refresh_token推荐

// 在登录成功后
const { data } = await supabase.auth.signInWithPassword({ email, password })

if (data.session) {
  const redirectUrl = new URL('cstb://auth', window.location.href)
  redirectUrl.searchParams.set('access_token', data.session.access_token)
  redirectUrl.searchParams.set('refresh_token', data.session.refresh_token)
  window.location.href = redirectUrl.toString()
}

方式 2: 使用 PKCE flow更安全

// 在登录页面初始化时
const { data } = await supabase.auth.signInWithOAuth({
  provider: 'email',
  options: {
    redirectTo: 'cstb://auth'
  }
})

// 处理回调
const { data: { session } } = await supabase.auth.getSession()
if (session) {
  window.location.href = 'cstb://auth?code=' + session.access_token
}

方式 3: 使用完整 session JSON

// 在登录成功后
const { data } = await supabase.auth.signInWithPassword({ email, password })

if (data.session) {
  const redirectUrl = new URL('cstb://auth', window.location.href)
  redirectUrl.searchParams.set('session', encodeURIComponent(JSON.stringify(data.session)))
  window.location.href = redirectUrl.toString()
}

4. 网页端修改示例

https://cstb.upup.cool/auth/loginhttps://cstb.upup.cool/auth/signup 页面中:

// 检查是否有 redirect 参数
const urlParams = new URLSearchParams(window.location.search)
const redirectTo = urlParams.get('redirect') // 应该是 'cstb://auth'

// 登录成功后
const handleLogin = async (email: string, password: string) => {
  const { data, error } = await supabase.auth.signInWithPassword({
    email,
    password,
  })

  if (error) {
    // 处理错误
    return
  }

  if (data.session && redirectTo) {
    // 重定向到 deep-link
    const redirectUrl = new URL(redirectTo)
    redirectUrl.searchParams.set('access_token', data.session.access_token)
    redirectUrl.searchParams.set('refresh_token', data.session.refresh_token)
    window.location.href = redirectUrl.toString()
  } else {
    // 正常网页端跳转
    window.location.href = '/'
  }
}

5. 环境变量

确保以下环境变量已配置:

NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key

6. 测试

  1. 启动应用
  2. 点击导航栏的用户图标
  3. 选择"登录"或"注册"
  4. 在浏览器中完成登录/注册
  5. 应用应该自动接收回调并显示登录成功提示

注意事项

  1. 安全性: 虽然 access_token 和 refresh_token 通过 URL 传递,但由于 deep-link 是本地协议,相对安全。但建议使用 PKCE flow 以获得更好的安全性。

  2. 错误处理: 网页端应该处理登录失败的情况,不要重定向到 deep-link。

  3. 用户体验: 可以在网页端显示"正在跳转到应用..."的提示,提升用户体验。

  4. 兼容性: 确保 deep-link 在所有目标平台上都已正确注册Windows/macOS/Linux

故障排查

  1. Deep-link 未触发: 检查 tauri.conf.json 中 deep-link 配置是否正确
  2. Session 未保存: 检查 Supabase client 配置,确保使用 localStorage
  3. 回调参数错误: 检查网页端传递的参数格式是否正确