Harden auth profile fallback for slow backend responses

This commit is contained in:
2569718930@qq.com
2026-04-15 22:40:01 +08:00
parent c4b45be757
commit 62298eaf38
2 changed files with 55 additions and 7 deletions
+48 -4
View File
@@ -16,10 +16,18 @@ export async function GET(req: NextRequest) {
try {
const auth = await buildBackendRequestHeaders(req);
const res = await fetch(`${API_BASE}/api/auth/me`, {
headers: auth.headers,
cache: "no-store",
});
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 6000);
let res: Response;
try {
res = await fetch(`${API_BASE}/api/auth/me`, {
headers: auth.headers,
cache: "no-store",
signal: controller.signal,
});
} finally {
clearTimeout(timeoutId);
}
if (res.status === 401 || res.status === 403) {
const response = NextResponse.json({
authenticated: false,
@@ -30,6 +38,23 @@ export async function GET(req: NextRequest) {
}
if (!res.ok) {
const raw = await res.text();
if (auth.authUserId) {
const response = NextResponse.json({
authenticated: true,
user_id: auth.authUserId,
email: auth.authEmail || null,
subscription_active: null,
subscription_plan_code: null,
subscription_expires_at: null,
subscription_total_expires_at: null,
subscription_queued_days: 0,
subscription_queued_count: 0,
points: 0,
degraded_auth_profile: true,
degraded_reason: `backend_${res.status}`,
});
return applyAuthResponseCookies(response, auth.response);
}
const response = NextResponse.json(
{ error: `Backend returned ${res.status}`, detail: raw.slice(0, 300) },
{ status: res.status },
@@ -40,9 +65,28 @@ export async function GET(req: NextRequest) {
const response = NextResponse.json(data);
return applyAuthResponseCookies(response, auth.response);
} catch (error) {
const auth = await buildBackendRequestHeaders(req);
if (auth.authUserId) {
const response = NextResponse.json({
authenticated: true,
user_id: auth.authUserId,
email: auth.authEmail || null,
subscription_active: null,
subscription_plan_code: null,
subscription_expires_at: null,
subscription_total_expires_at: null,
subscription_queued_days: 0,
subscription_queued_count: 0,
points: 0,
degraded_auth_profile: true,
degraded_reason: String(error),
});
return applyAuthResponseCookies(response, auth.response);
}
return NextResponse.json(
{ error: "Failed to fetch auth profile", detail: String(error) },
{ status: 500 },
);
}
}
+7 -3
View File
@@ -9,6 +9,8 @@ export const FORWARDED_SUPABASE_EMAIL_HEADER = "x-polyweather-auth-email";
type HeaderBuildResult = {
headers: HeadersInit;
response: NextResponse | null;
authUserId?: string | null;
authEmail?: string | null;
};
type HeaderBuildOptions = {
@@ -59,20 +61,20 @@ export async function buildBackendRequestHeaders(
if (incomingAuth) {
headers.set("Authorization", `Bearer ${incomingAuth}`);
return { headers, response: passthroughResponse };
return { headers, response: passthroughResponse, authUserId: forwardedUserId || null, authEmail: forwardedEmail || null };
}
const accessToken = session?.access_token || "";
if (accessToken) {
// Fallback to cookie-backed session when request does not carry bearer.
headers.set("Authorization", `Bearer ${accessToken}`);
}
return { headers, response: passthroughResponse };
return { headers, response: passthroughResponse, authUserId: forwardedUserId || null, authEmail: forwardedEmail || null };
}
if (incomingAuth) {
headers.set("Authorization", `Bearer ${incomingAuth}`);
}
return { headers, response: null };
return { headers, response: null, authUserId: null, authEmail: null };
}
export function applyAuthResponseCookies(
@@ -87,3 +89,5 @@ export function applyAuthResponseCookies(
}
return target;
}