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) { try { const body = await request.json(); const { code, state, inviteCode } = body; // 验证必需参数 if (!code || !state) { return NextResponse.json( { success: false, message: 'Missing required parameters: code and state' }, { status: 400 } ); } // 解析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向Google换取access token和id_token const googleClientId = '847079918888-o1nne8d3ij80dn20qurivo987pv07225.apps.googleusercontent.com'; const googleClientSecret = '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'; // 需要设置环境变量 if (!googleClientSecret) { console.error('Google Client Secret未配置'); return NextResponse.json( { success: false, message: 'Google Client Secret not configured' }, { status: 500 } ); } const tokenResponse = await fetch('https://oauth2.googleapis.com/token', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: new URLSearchParams({ code, client_id: googleClientId, client_secret: googleClientSecret, redirect_uri: getRedirectUri(request), grant_type: 'authorization_code', }), }); if (!tokenResponse.ok) { const errorText = await tokenResponse.text(); console.error('Google token exchange failed:', errorText); return NextResponse.json( { success: false, message: 'Failed to exchange authorization code for tokens' }, { status: 400 } ); } const tokenData = await tokenResponse.json(); const { id_token } = tokenData; if (!id_token) { console.error('No id_token received from Google'); return NextResponse.json( { success: false, message: 'No id_token received from Google' }, { status: 400 } ); } // 第二步:使用id_token调用Java后端 const javaBaseUrl = process.env.NEXT_PUBLIC_JAVA_URL || 'https://77.app.java.auth.qikongjian.com'; const backendResponse = await fetch(`${javaBaseUrl}/api/auth/google/login`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, body: JSON.stringify({ idToken: id_token, // 使用从Google获取的id_token action: 'auto', // 自动判断登录或注册 inviteCode: inviteCode || stateData.inviteCode || undefined }) }); const backendResult = await backendResponse.json(); if (!backendResponse.ok || !backendResult.success) { console.error('Java后端处理Google OAuth失败:', backendResult); return NextResponse.json( { success: false, message: backendResult.message || 'Google authentication failed' }, { status: backendResponse.status || 500 } ); } console.log('Google OAuth认证成功:', { userId: backendResult.data?.user?.userId, email: backendResult.data?.user?.email }); // 返回成功结果 return NextResponse.json({ success: true, data: { token: backendResult.data.token, user: backendResult.data.userInfo || backendResult.data.user, message: 'Google authentication successful' } }); } catch (error: any) { console.error('Google OAuth回调处理错误:', error); 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') || ''; const protocol = request.headers.get('x-forwarded-proto') || 'https'; if (host.includes('localhost') || host.includes('127.0.0.1')) { 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请求(如果需要) */ export async function GET(request: NextRequest) { return NextResponse.json( { success: false, message: 'This endpoint only accepts POST requests' }, { status: 405 } ); }