diff --git a/src/actions/user-authorize.ts b/src/actions/user-authorize.ts index d18ce64..d69d51b 100644 --- a/src/actions/user-authorize.ts +++ b/src/actions/user-authorize.ts @@ -1,6 +1,5 @@ "use server"; -import { cookies } from "next/headers"; import { redirect } from "next/navigation"; import { signIn as nextSignIn } from "@/auth"; @@ -11,40 +10,18 @@ export async function signIn(data: Record) { // 进行 SSO 登录 await nextSignIn("credentials", { sso, sig }); - // 检查是否有保存的 OAuth 参数 - const cookieStore = cookies(); - const oauthParams = cookieStore.get("oauth_params"); + // 从 sso 参数中获取 return_sso_url + const params = new URLSearchParams(atob(sso)); + const returnSsoUrl = params.get("return_sso_url"); - if (oauthParams) { - // 清除 cookie - cookieStore.set("oauth_params", "", { maxAge: 0 }); - - // 解析原始的 OAuth 参数 - const params = new URLSearchParams(oauthParams.value); - const clientId = params.get("client_id"); - const redirectUri = params.get("redirect_uri"); - const state = params.get("state"); - const scope = params.get("scope") || "read_profile"; - - // 重新构建授权页面 URL - const authParams = new URLSearchParams({ - response_type: "code", - client_id: clientId || "", - redirect_uri: redirectUri || "", - scope, - }); - if (state) { - authParams.set("state", state); - } - - // 重定向到 OAuth 授权页面 - redirect(`/oauth/authorize?${authParams.toString()}`); + if (!returnSsoUrl) { + redirect("/dashboard"); } - // 如果没有 OAuth 参数,重定向到仪表板 - redirect("/dashboard"); + // 重定向到 return_sso_url + redirect(returnSsoUrl); } catch (error) { console.error("登录失败:", error); - throw error; + redirect("/sign-in?error=AuthenticationError"); } } diff --git a/src/app/(auth)/authorize/callback/page.tsx b/src/app/(auth)/authorize/callback/page.tsx deleted file mode 100644 index 237d499..0000000 --- a/src/app/(auth)/authorize/callback/page.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { redirect } from "next/navigation"; -import { signIn } from "@/actions/user-authorize"; - -interface CallbackParams { - sso: string; - sig: string; -} - -export default async function AuthorizeCallbackPage({ - searchParams, -}: { - searchParams: CallbackParams; -}) { - const { sso, sig } = searchParams; - - if (!sso || !sig) { - redirect("/sign-in?error=InvalidCallback"); - } - - try { - // 进行 SSO 登录 - await signIn({ sso, sig }); - } catch (error) { - console.error("登录失败:", error); - redirect("/sign-in?error=AuthenticationError"); - } -} diff --git a/src/app/api/auth/q58/route.ts b/src/app/api/auth/q58/route.ts index b7b354f..f86ba11 100644 --- a/src/app/api/auth/q58/route.ts +++ b/src/app/api/auth/q58/route.ts @@ -13,23 +13,22 @@ export async function POST(req: Request) { try { const nonce = WordArray.random(16).toString(); - // 从请求中获取 OAuth 参数 - const body = await req.json().catch(() => ({})); - const oauthParams = body.oauth_params || ""; - - // 设置回调地址 - const return_url = `${hostUrl}/authorize/callback`; - - // 如果有 OAuth 参数,保存到 cookie - if (oauthParams) { - cookies().set("oauth_params", oauthParams, { - maxAge: 60 * 10, // 10分钟过期 - path: "/", - httpOnly: true, - secure: process.env.NODE_ENV === "production", - }); + // 尝试从请求体中获取 OAuth 参数 + let oauthParams = ""; + try { + const body = await req.json(); + if (body.oauth_params) { + oauthParams = body.oauth_params; + } + } catch (error) { + console.error("Failed to parse request body:", error); } + // 设置回调地址,如果有 OAuth 参数则回到授权页面 + const return_url = oauthParams + ? `${hostUrl}/authorize?${oauthParams}` + : `${hostUrl}/dashboard`; + // 构建 SSO 参数 const ssoParams = new URLSearchParams(); ssoParams.set("nonce", nonce); diff --git a/src/components/auth/user-auth-form.tsx b/src/components/auth/user-auth-form.tsx index 0177179..afbd95e 100644 --- a/src/components/auth/user-auth-form.tsx +++ b/src/components/auth/user-auth-form.tsx @@ -1,7 +1,7 @@ "use client"; import * as React from "react"; -import { useRouter } from "next/navigation"; +import { useRouter, useSearchParams } from "next/navigation"; import { Loader2, MessageCircleCode } from "lucide-react"; import { cn } from "@/lib/utils"; @@ -18,17 +18,26 @@ export function UserAuthForm({ }: React.HTMLAttributes) { const [isLoading, setIsLoading] = React.useState(false); const { toast } = useToast(); + const searchParams = useSearchParams(); const signIn = async () => { if (isLoading) return; setIsLoading(true); try { + // 构建请求体,包含 OAuth 参数 + const body: Record = {}; + const currentParams = searchParams?.toString(); + if (currentParams) { + body.oauth_params = currentParams; + } + const response = await fetch("/api/auth/q58", { method: "POST", headers: { "Content-Type": "application/json", }, + body: JSON.stringify(body), }); if (!response.ok) { diff --git a/src/components/auth/user-authorize.tsx b/src/components/auth/user-authorize.tsx index 4d439b5..26b7136 100644 --- a/src/components/auth/user-authorize.tsx +++ b/src/components/auth/user-authorize.tsx @@ -1,6 +1,8 @@ "use client"; -import { useRouter } from "next/navigation"; +import { useCallback, useEffect, useState } from "react"; +import { useRouter, useSearchParams } from "next/navigation"; +import { signIn } from "@/actions/user-authorize"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; @@ -13,6 +15,65 @@ export function UserAuthorize({ data, ...props }: UserAuthorizeProps) { + const [isLoading, setIsLoading] = useState(false); + const [error, setError] = useState(null); + const router = useRouter(); + const searchParams = useSearchParams(); + + const signInCallback = useCallback(async () => { + if (isLoading) { + return; + } + setIsLoading(true); + try { + // 从 URL 中获取 sso 和 sig 参数 + const sso = searchParams?.get("sso"); + const sig = searchParams?.get("sig"); + + if (!sso || !sig) { + // 如果没有 SSO 参数,说明是 OAuth 流程,跳转到登录页 + router.push(`/sign-in?${searchParams?.toString()}`); + return; + } + + // 传递 SSO 参数 + await signIn({ + sso, + sig, + }); + } catch (error) { + console.error("登录过程出错:", error); + setError(error); + setIsLoading(false); + } + }, [isLoading, router, searchParams]); + + useEffect(() => { + signInCallback(); + }, [signInCallback]); + + if (error) { + return ( + + +
+
+
+ + 授权失败 + +
+ +

+ {error instanceof Error + ? error.message + : "登录异常,授权失败!请稍后重试。"} +

+
+
+ ); + } + return ( @@ -23,7 +84,7 @@ export function UserAuthorize({

- 请稍候,我们正在处理您的授权请求 + {isLoading ? "请稍候,我们正在处理您的授权请求" : "正在跳转..."}