import { NextRequest, NextResponse } from 'next/server'; import type { OAuthCallbackParams } from '@/app/types/google-oauth'; /** * Google OAuth回调处理API * 处理从Google OAuth返回的授权码,完成用户认证 */ export async function POST(request: NextRequest) { console.log('🎯 Google OAuth Callback API 被调用'); console.log('📍 Request URL:', request.url); console.log('📍 Request method:', request.method); try { const body = await request.json(); console.log('📦 Request body:', body); const { code, state, inviteCode } = body; // 验证必需参数 if (!code || !state) { return NextResponse.json( { success: false, message: 'Missing required parameters: code and state' }, { status: 400 } ); } // 移除开发模式模拟,始终调用真实接口 console.log('🚀 开始处理Google OAuth回调,调用真实接口'); // 解析state参数 let stateData: any = {}; try { stateData = JSON.parse(state); } catch (e) { console.warn('无法解析state参数:', state); return NextResponse.json( { success: false, message: 'Invalid state parameter' }, { status: 400 } ); } console.log('Google OAuth回调处理开始:', { codeLength: code.length, stateData, inviteCode }); // 直接将authorization code传递给Java后端处理 console.log('准备调用Java后端验证Google authorization code...'); // 第二步:调用Java验证接口(只验证不创建用户) const javaBaseUrl = process.env.NEXT_PUBLIC_JAVA_URL || 'https://auth.test.movieflow.ai'; console.log('🔧 环境变量 NEXT_PUBLIC_JAVA_URL:', process.env.NEXT_PUBLIC_JAVA_URL); console.log('🔧 最终使用的 javaBaseUrl:', javaBaseUrl); console.log('开始调用Java验证接口:', javaBaseUrl); const verifyResponse = await fetch(`${javaBaseUrl}/api/auth/google/callback`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, body: JSON.stringify({ code: code, // Google authorization code state: state, // state参数 inviteCode: inviteCode || stateData.inviteCode || undefined, skipUserCreation: true // 🔑 关键:只验证不创建用户 }) }); console.log('Java验证接口响应状态:', verifyResponse.status); const verifyResult = await verifyResponse.json(); if (!verifyResponse.ok || !verifyResult.success) { console.error('Java验证接口处理失败:', verifyResult); return NextResponse.json( { success: false, message: verifyResult.message || 'Google token verification failed' }, { status: verifyResponse.status || 500 } ); } console.log('Google Token验证成功:', { email: verifyResult.data?.email, name: verifyResult.data?.name }); // 第三步:调用Python注册接口进行用户创建和积分发放 const smartvideoBaseUrl = process.env.NEXT_PUBLIC_BASE_URL || 'https://77.smartvideo.py.qikongjian.com'; console.log('开始调用Python注册接口:', smartvideoBaseUrl); const registerResponse = await fetch(`${smartvideoBaseUrl}/api/user_fission/register_with_invite`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, body: JSON.stringify({ email: verifyResult.data.email, name: verifyResult.data.name, auth_type: 'GOOGLE', google_user_info: verifyResult.data, invite_code: inviteCode || stateData.inviteCode || undefined }) }); console.log('Python注册接口响应状态:', registerResponse.status); const registerResult = await registerResponse.json(); if (!registerResponse.ok || !registerResult.successful) { console.error('Python注册接口处理失败:', registerResult); return NextResponse.json( { success: false, message: registerResult.message || 'User registration failed' }, { status: registerResponse.status || 500 } ); } console.log('Google OAuth注册成功:', { userId: registerResult.data?.user_id, email: registerResult.data?.email }); // 返回成功结果(统一格式) return NextResponse.json({ success: true, data: { token: registerResult.data.token, user: { userId: registerResult.data.user_id, userName: registerResult.data.name, name: registerResult.data.name, email: registerResult.data.email, authType: registerResult.data.auth_type, isNewUser: true }, message: 'Google OAuth registration successful with credit rewards' } }); } catch (error: any) { console.error('Google OAuth回调处理错误:', error); // 检查是否是网络连接错误 if (error.code === 'ECONNREFUSED' || error.message?.includes('fetch failed')) { console.error('网络连接失败,可能是Java后端服务不可用'); return NextResponse.json( { success: false, message: 'Backend service unavailable. Please try again later.' }, { status: 503 } ); } return NextResponse.json( { success: false, message: error.message || 'Internal server error during Google OAuth callback' }, { status: 500 } ); } } /** * 根据请求获取正确的redirect_uri */ function getRedirectUri(request: NextRequest): string { const host = request.headers.get('host') || ''; if (host.includes('localhost') || host.includes('127.0.0.1')) { // 本地开发环境:使用实际的端口号(可能是3000或3001) const protocol = 'http'; return `${protocol}://${host}/api/auth/google/callback`; } else if (host.includes('movieflow.net')) { return 'https://www.movieflow.net/api/auth/google/callback'; } else if (host.includes('movieflow.ai')) { return 'https://www.movieflow.ai/api/auth/google/callback'; } else { // 默认使用生产环境 return 'https://www.movieflow.ai/api/auth/google/callback'; } } /** * 处理GET请求 - Google OAuth回调 * 将GET请求重定向到页面路由进行处理 */ export async function GET(request: NextRequest) { const { searchParams } = new URL(request.url); const code = searchParams.get('code'); const state = searchParams.get('state'); if (!code || !state) { return NextResponse.json( { success: false, message: 'Missing required parameters: code and state' }, { status: 400 } ); } // 重定向到页面路由,让页面处理OAuth回调 const callbackUrl = `/users/oauth/callback?code=${encodeURIComponent(code)}&state=${encodeURIComponent(state)}`; // 修复:确保使用正确的域名进行重定向 const host = request.headers.get('host') || 'www.movieflow.net'; const protocol = request.headers.get('x-forwarded-proto') || 'https'; const fullCallbackUrl = `${protocol}://${host}${callbackUrl}`; console.log('🔍 前端API重定向调试:'); console.log(' - request.url:', request.url); console.log(' - host header:', host); console.log(' - protocol:', protocol); console.log(' - 重定向到:', fullCallbackUrl); return NextResponse.redirect(fullCallbackUrl); }