紧急回滚

This commit is contained in:
Zixin Zhou 2025-09-22 20:33:43 +08:00
parent ca4408f5df
commit 735d90bbd7

View File

@ -13,21 +13,21 @@ export async function POST(request: NextRequest) {
// 验证必需参数
if (!code || !state) {
return NextResponse.json(
{
success: false,
message: 'Missing required parameters: code and state'
},
{ status: 400 }
{
success: false,
message: 'Missing required parameters: code and state'
},
{ status: 400 }
);
}
// 开发模式使用测试环境的OAuth处理
const isDevelopment = process.env.NODE_ENV === 'development';
const useTestEnv = isDevelopment; // 开发环境默认使用测试环境
if (useTestEnv) {
console.log('🧪 开发模式使用模拟OAuth响应');
// 解析state参数获取origin信息
let stateData: any = {};
try {
@ -35,7 +35,7 @@ export async function POST(request: NextRequest) {
} catch (e) {
console.warn('无法解析state参数:', state);
}
// 模拟成功的OAuth响应
const mockResponse = {
success: true,
@ -60,7 +60,7 @@ export async function POST(request: NextRequest) {
message: 'Development mode - Google authentication simulated'
}
};
console.log('返回模拟OAuth响应:', mockResponse);
return NextResponse.json(mockResponse);
}
@ -72,11 +72,11 @@ export async function POST(request: NextRequest) {
} catch (e) {
console.warn('无法解析state参数:', state);
return NextResponse.json(
{
success: false,
message: 'Invalid state parameter'
},
{ status: 400 }
{
success: false,
message: 'Invalid state parameter'
},
{ status: 400 }
);
}
@ -89,20 +89,20 @@ export async function POST(request: NextRequest) {
// 第一步使用authorization code向Google换取access token和id_token
const googleClientId = process.env.NEXT_PUBLIC_GOOGLE_CLIENT_ID || '847079918888-o1nne8d3ij80dn20qurivo987pv07225.apps.googleusercontent.com';
const googleClientSecret = process.env.GOOGLE_CLIENT_SECRET || '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';
if (!googleClientSecret) {
console.error('Google Client Secret未配置');
return NextResponse.json(
{
success: false,
message: 'Google Client Secret not configured'
},
{ status: 500 }
{
success: false,
message: 'Google Client Secret not configured'
},
{ status: 500 }
);
}
console.log('开始向Google交换token...');
// 创建fetch配置包含超时和重试机制
const fetchOptions = {
method: 'POST',
@ -125,32 +125,32 @@ export async function POST(request: NextRequest) {
tokenResponse = await fetch('https://oauth2.googleapis.com/token', fetchOptions);
} catch (fetchError: any) {
console.error('Google API连接失败:', fetchError.message);
// 如果是超时错误,提供更友好的错误信息
if (fetchError.name === 'TimeoutError' || fetchError.code === 'UND_ERR_CONNECT_TIMEOUT') {
return NextResponse.json(
{
success: false,
message: 'Google authentication service is temporarily unavailable. Please check your network connection and try again.'
},
{ status: 503 }
{
success: false,
message: 'Google authentication service is temporarily unavailable. Please check your network connection and try again.'
},
{ status: 503 }
);
}
throw fetchError;
}
console.log('Google token exchange响应状态:', tokenResponse.status);
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 }
{
success: false,
message: 'Failed to exchange authorization code for tokens'
},
{ status: 400 }
);
}
@ -161,109 +161,81 @@ export async function POST(request: NextRequest) {
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 }
{
success: false,
message: 'No id_token received from Google'
},
{ status: 400 }
);
}
// 第二步使用id_token调用smartvideo-server的register_with_invite接口
const smartvideoBaseUrl = process.env.NEXT_PUBLIC_SMARTVIDEO_URL;
console.log('开始调用smartvideo-server后端:', smartvideoBaseUrl);
// 从Google ID Token中解析用户信息简单解析仅用于获取email等基本信息
let googleUserInfo: any = {};
try {
// 解码Google ID Token的payload部分注意这里只是为了获取基本信息真正的验证在后端进行
const tokenParts = id_token.split('.');
if (tokenParts.length === 3) {
const payload = JSON.parse(atob(tokenParts[1]));
googleUserInfo = {
email: payload.email,
name: payload.name,
given_name: payload.given_name,
family_name: payload.family_name
};
}
} catch (e) {
console.warn('解析Google ID Token失败使用空的用户信息:', e);
}
const backendResponse = await fetch(`${smartvideoBaseUrl}/api/user_fission/register_with_invite`, {
// 第二步使用id_token调用Java后端
const javaBaseUrl = process.env.NEXT_PUBLIC_JAVA_URL || 'https://auth.test.movieflow.ai';
console.log('开始调用Java后端:', javaBaseUrl);
const backendResponse = await fetch(`${javaBaseUrl}/api/auth/google/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: JSON.stringify({
email: googleUserInfo.email, // 从Google Token中获取的邮箱
name: googleUserInfo.name, // 从Google Token中获取的姓名
google_id_token: id_token, // Google ID Token
auth_type: 'GOOGLE', // 标识为Google OAuth注册
invite_code: inviteCode || stateData.inviteCode || undefined
idToken: id_token, // 使用从Google获取的id_token
action: 'auto', // 自动判断登录或注册
inviteCode: inviteCode || stateData.inviteCode || undefined
})
});
console.log('smartvideo-server后端响应状态:', backendResponse.status);
console.log('Java后端响应状态:', backendResponse.status);
const backendResult = await backendResponse.json();
if (!backendResponse.ok || !backendResult.successful) {
console.error('smartvideo-server处理Google OAuth失败:', backendResult);
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 }
{
success: false,
message: backendResult.message || 'Google authentication failed'
},
{ status: backendResponse.status || 500 }
);
}
console.log('Google OAuth认证成功:', {
userId: backendResult.data?.user_id,
email: backendResult.data?.email
userId: backendResult.data?.user?.userId,
email: backendResult.data?.user?.email
});
// 返回成功结果,格式与原有保持一致以确保前端兼容性
// 返回成功结果
return NextResponse.json({
success: true,
data: {
// 包含token以支持前端认证
token: backendResult.data.token,
user: {
userId: backendResult.data.user_id,
userName: backendResult.data.name,
name: backendResult.data.name,
email: backendResult.data.email,
authType: backendResult.data.auth_type,
isNewUser: true // 通过register_with_invite接口的都是新用户或首次OAuth绑定
},
message: 'Google OAuth registration successful with credit rewards'
user: backendResult.data.userInfo || backendResult.data.user,
message: 'Google authentication successful'
}
});
} 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 }
{
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 }
{
success: false,
message: error.message || 'Internal server error during Google OAuth callback'
},
{ status: 500 }
);
}
}
@ -273,7 +245,7 @@ export async function POST(request: NextRequest) {
*/
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';
@ -296,30 +268,30 @@ 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 }
{
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);
}