This commit is contained in:
MarkLo 2025-12-13 06:42:20 +08:00
parent 2a65c7f44d
commit 7926eb74b4
2 changed files with 31 additions and 4 deletions

View File

@ -2,6 +2,7 @@
Google OAuth authentication routes Google OAuth authentication routes
""" """
import os import os
import logging
import httpx import httpx
from datetime import datetime from datetime import datetime
from typing import Optional from typing import Optional
@ -13,6 +14,8 @@ from sqlalchemy import select
from backend.app.db import get_db, User, UserSettings from backend.app.db import get_db, User, UserSettings
from backend.app.services.auth_utils import create_access_token from backend.app.services.auth_utils import create_access_token
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/api/auth", tags=["Authentication"]) router = APIRouter(prefix="/api/auth", tags=["Authentication"])
# Google OAuth Configuration - read at request time for dynamic updates # Google OAuth Configuration - read at request time for dynamic updates
@ -23,7 +26,9 @@ def get_google_client_secret():
return os.getenv("GOOGLE_CLIENT_SECRET", "") return os.getenv("GOOGLE_CLIENT_SECRET", "")
def get_frontend_url(): def get_frontend_url():
return os.getenv("FRONTEND_URL", "http://localhost:3000") url = os.getenv("FRONTEND_URL", "http://localhost:3000")
logger.info(f"FRONTEND_URL resolved to: {url}")
return url
# Google OAuth URLs # Google OAuth URLs
GOOGLE_AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth" GOOGLE_AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth"

View File

@ -4,27 +4,49 @@
*/ */
import { NextRequest, NextResponse } from "next/server"; import { NextRequest, NextResponse } from "next/server";
// Get the proper base URL from request headers (handles Railway proxy)
function getBaseUrl(request: NextRequest): string {
// Try to get the forwarded host first (used by proxies like Railway)
const forwardedHost = request.headers.get("x-forwarded-host");
const forwardedProto = request.headers.get("x-forwarded-proto") || "https";
if (forwardedHost) {
return `${forwardedProto}://${forwardedHost}`;
}
// Fall back to host header
const host = request.headers.get("host");
if (host && !host.startsWith("0.0.0.0") && !host.startsWith("localhost")) {
return `https://${host}`;
}
// Last resort: use environment variable
return process.env.NEXT_PUBLIC_SITE_URL || "http://localhost:3000";
}
export async function GET(request: NextRequest) { export async function GET(request: NextRequest) {
const searchParams = request.nextUrl.searchParams; const searchParams = request.nextUrl.searchParams;
const code = searchParams.get("code"); const code = searchParams.get("code");
const error = searchParams.get("error"); const error = searchParams.get("error");
const baseUrl = getBaseUrl(request);
// Handle OAuth errors // Handle OAuth errors
if (error) { if (error) {
return NextResponse.redirect( return NextResponse.redirect(
new URL(`/auth/callback?error=${encodeURIComponent(error)}`, request.url) new URL(`/auth/callback?error=${encodeURIComponent(error)}`, baseUrl)
); );
} }
// Redirect to callback page with code // Redirect to callback page with code
if (code) { if (code) {
return NextResponse.redirect( return NextResponse.redirect(
new URL(`/auth/callback?code=${encodeURIComponent(code)}`, request.url) new URL(`/auth/callback?code=${encodeURIComponent(code)}`, baseUrl)
); );
} }
// No code or error // No code or error
return NextResponse.redirect( return NextResponse.redirect(
new URL("/auth/callback?error=no_code", request.url) new URL("/auth/callback?error=no_code", baseUrl)
); );
} }