From 178d2af9aabee4cf91f6f98d02940123ce4a2118 Mon Sep 17 00:00:00 2001 From: wood chen Date: Fri, 21 Feb 2025 17:58:58 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=B9=E8=BF=9B=20OAuth=20=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E5=AD=98=E5=82=A8=E5=92=8C=E5=A4=84=E7=90=86=E6=9C=BA?= =?UTF-8?q?=E5=88=B6=EF=BC=8C=E4=BC=98=E5=8C=96=E8=B7=A8=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E4=BC=A0=E9=80=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/actions/user-authorize.ts | 19 ++++++++++++++----- src/app/api/auth/q58/route.ts | 9 ++++++--- src/components/auth/user-auth-form.tsx | 12 ++++++++++-- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/actions/user-authorize.ts b/src/actions/user-authorize.ts index ecaf92f..c3430d4 100644 --- a/src/actions/user-authorize.ts +++ b/src/actions/user-authorize.ts @@ -18,13 +18,22 @@ export async function signIn(data: Record) { redirect("/dashboard"); } - // 检查是否是 OAuth 流程 + // 检查是否有保存的 OAuth 参数 + const cookieStore = cookies(); + const savedOAuthParams = cookieStore.get("oauth_params"); + + if (savedOAuthParams) { + // 清除保存的参数 + cookieStore.delete("oauth_params"); + // 重定向到 OAuth 授权页面 + redirect(`/oauth/authorize?${savedOAuthParams.value}`); + } + + // 如果没有 OAuth 参数,尝试解析 return_sso_url try { const returnUrl = new URL(returnSsoUrl); - const isOAuthFlow = returnUrl.pathname.startsWith("/oauth/authorize"); - - if (isOAuthFlow) { - // 如果是 OAuth 流程,继续授权流程 + if (returnUrl.pathname === "/authorize") { + // 如果是授权页面,直接重定向 redirect(returnSsoUrl); } } catch (error) { diff --git a/src/app/api/auth/q58/route.ts b/src/app/api/auth/q58/route.ts index 4635c10..93b6303 100644 --- a/src/app/api/auth/q58/route.ts +++ b/src/app/api/auth/q58/route.ts @@ -33,9 +33,12 @@ export async function POST(req: Request) { ? `${hostUrl}/authorize?${oauthParams}` // OAuth流程:回到授权页面 : `${hostUrl}/dashboard`; // 普通登录:直接到仪表板 - const sso = btoa( - `nonce=${nonce}&return_sso_url=${encodeURIComponent(return_url)}`, - ); + // 构建 SSO 参数 + const ssoParams = new URLSearchParams(); + ssoParams.set("nonce", nonce); + ssoParams.set("return_sso_url", return_url); + + const sso = btoa(ssoParams.toString()); const sig = hmacSHA256(sso, clientSecret).toString(Hex); cookies().set(AUTH_NONCE, nonce, { maxAge: 60 * 10 }); diff --git a/src/components/auth/user-auth-form.tsx b/src/components/auth/user-auth-form.tsx index 6dda46c..75af5b6 100644 --- a/src/components/auth/user-auth-form.tsx +++ b/src/components/auth/user-auth-form.tsx @@ -21,13 +21,21 @@ export function UserAuthForm({ const { toast } = useToast(); const searchParams = useSearchParams(); + // 在组件挂载时保存 OAuth 参数 + React.useEffect(() => { + if (searchParams?.toString()) { + localStorage.setItem("oauth_params", searchParams.toString()); + } + }, [searchParams]); + const signIn = () => { React.startTransition(async () => { try { // 构建请求体,包含 OAuth 参数 const body: Record = {}; - if (searchParams?.toString()) { - body.oauth_params = searchParams.toString(); + const savedParams = localStorage.getItem("oauth_params"); + if (savedParams) { + body.oauth_params = savedParams; } const response = await fetch("/api/auth/q58", {