# 网页端集成示例代码 本文档提供网页端(https://cstb.upup.cool/)实现登录/注册回调的示例代码。 ## 登录页面示例 在 `auth/login` 页面中: ```typescript 'use client' import { useState } from 'react' import { createClient } from '@/utils/supabase/client' import { useSearchParams } from 'next/navigation' export default function LoginPage() { const [email, setEmail] = useState('') const [password, setPassword] = useState('') const [loading, setLoading] = useState(false) const searchParams = useSearchParams() const redirectTo = searchParams.get('redirect') // 应该是 'cstb://auth' const supabase = createClient() const handleLogin = async (e: React.FormEvent) => { e.preventDefault() setLoading(true) try { const { data, error } = await supabase.auth.signInWithPassword({ email, password, }) if (error) { alert(`登录失败: ${error.message}`) setLoading(false) return } if (data.session) { // 如果有 redirect 参数,说明是从应用跳转过来的 if (redirectTo) { // 构建 deep-link URL 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 = '/' } } } catch (error) { console.error('Login error:', error) alert('登录时发生错误') setLoading(false) } } return (
) } ``` ## 注册页面示例 在 `auth/signup` 页面中: ```typescript 'use client' import { useState } from 'react' import { createClient } from '@/utils/supabase/client' import { useSearchParams } from 'next/navigation' export default function SignupPage() { const [email, setEmail] = useState('') const [password, setPassword] = useState('') const [confirmPassword, setConfirmPassword] = useState('') const [loading, setLoading] = useState(false) const searchParams = useSearchParams() const redirectTo = searchParams.get('redirect') // 应该是 'cstb://auth' const supabase = createClient() const handleSignup = async (e: React.FormEvent) => { e.preventDefault() if (password !== confirmPassword) { alert('两次输入的密码不一致') return } setLoading(true) try { const { data, error } = await supabase.auth.signUp({ email, password, }) if (error) { alert(`注册失败: ${error.message}`) setLoading(false) return } if (data.session) { // 如果有 redirect 参数,说明是从应用跳转过来的 if (redirectTo) { // 构建 deep-link URL 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 { // 正常网页端跳转 alert('注册成功!请检查邮箱验证链接。') window.location.href = '/' } } else { // 需要邮箱验证 alert('注册成功!请检查邮箱中的验证链接。') if (!redirectTo) { window.location.href = '/' } } } catch (error) { console.error('Signup error:', error) alert('注册时发生错误') setLoading(false) } } return ( ) } ``` ## 使用 OAuth 提供商的示例 如果使用第三方登录(如 Google、GitHub 等): ```typescript const handleOAuthLogin = async (provider: 'google' | 'github') => { const { data, error } = await supabase.auth.signInWithOAuth({ provider, options: { redirectTo: redirectTo || `${window.location.origin}/auth/callback`, }, }) if (error) { alert(`登录失败: ${error.message}`) return } // OAuth 会重定向到回调页面,在回调页面中处理 } ``` ## 回调页面处理 如果需要处理 OAuth 回调: ```typescript // auth/callback/page.tsx 'use client' import { useEffect } from 'react' import { createClient } from '@/utils/supabase/client' import { useSearchParams } from 'next/navigation' export default function CallbackPage() { const searchParams = useSearchParams() const redirectTo = searchParams.get('redirect') // 从应用跳转时的原始 redirect useEffect(() => { const handleCallback = async () => { const supabase = createClient() const { data: { session }, error } = await supabase.auth.getSession() if (error) { console.error('Error getting session:', error) return } if (session) { // 如果是从应用跳转过来的,重定向回应用 if (redirectTo) { const redirectUrl = new URL(redirectTo) redirectUrl.searchParams.set('access_token', session.access_token) redirectUrl.searchParams.set('refresh_token', session.refresh_token) window.location.href = redirectUrl.toString() } else { // 正常网页端跳转 window.location.href = '/' } } } void handleCallback() }, [redirectTo]) return