From 05b8ee3c750663e7c12474017d762bbc0966550c Mon Sep 17 00:00:00 2001 From: wood chen Date: Fri, 21 Feb 2025 18:18:45 +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=E9=87=8D=E5=AE=9A=E5=90=91?= =?UTF-8?q?=E6=9C=BA=E5=88=B6=EF=BC=8C=E4=BD=BF=E7=94=A8=20cookies=20?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E4=B8=B4=E6=97=B6=E6=8E=88=E6=9D=83=E5=8F=82?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/actions/user-authorize.ts | 18 +++++++++++------- src/app/api/auth/q58/route.ts | 14 +++++++++++++- src/components/auth/user-authorize.tsx | 10 +++++----- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/actions/user-authorize.ts b/src/actions/user-authorize.ts index d69d51b..a6585f2 100644 --- a/src/actions/user-authorize.ts +++ b/src/actions/user-authorize.ts @@ -1,5 +1,6 @@ "use server"; +import { cookies } from "next/headers"; import { redirect } from "next/navigation"; import { signIn as nextSignIn } from "@/auth"; @@ -10,16 +11,19 @@ export async function signIn(data: Record) { // 进行 SSO 登录 await nextSignIn("credentials", { sso, sig }); - // 从 sso 参数中获取 return_sso_url - const params = new URLSearchParams(atob(sso)); - const returnSsoUrl = params.get("return_sso_url"); + // 检查是否有保存的 OAuth 参数 + const cookieStore = cookies(); + const oauthParams = cookieStore.get("oauth_params"); - if (!returnSsoUrl) { - redirect("/dashboard"); + if (oauthParams) { + // 清除 cookie + cookieStore.delete("oauth_params"); + // 重定向到授权页面,带上 OAuth 参数 + redirect(`/oauth/authorize?${oauthParams.value}`); } - // 重定向到 return_sso_url - redirect(returnSsoUrl); + // 如果没有 OAuth 参数,重定向到仪表板 + redirect("/dashboard"); } 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 815db09..18d7f18 100644 --- a/src/app/api/auth/q58/route.ts +++ b/src/app/api/auth/q58/route.ts @@ -13,8 +13,20 @@ 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 || ""; + + // 设置回调地址,如果有 OAuth 参数则保存 const return_url = `${hostUrl}/authorize`; + if (oauthParams) { + cookies().set("oauth_params", oauthParams, { + maxAge: 60 * 10, // 10分钟过期 + path: "/", + httpOnly: true, + secure: process.env.NODE_ENV === "production", + }); + } // 构建 SSO 参数 const ssoParams = new URLSearchParams(); diff --git a/src/components/auth/user-authorize.tsx b/src/components/auth/user-authorize.tsx index 1c131df..bbc7038 100644 --- a/src/components/auth/user-authorize.tsx +++ b/src/components/auth/user-authorize.tsx @@ -1,7 +1,7 @@ "use client"; import { useCallback, useEffect, useState } from "react"; -import { useRouter } from "next/navigation"; +import { useRouter, useSearchParams } from "next/navigation"; import { signIn } from "@/actions/user-authorize"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; @@ -18,6 +18,7 @@ export function UserAuthorize({ const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(null); const router = useRouter(); + const searchParams = useSearchParams(); const signInCallback = useCallback(async () => { if (isLoading) { @@ -26,9 +27,8 @@ export function UserAuthorize({ setIsLoading(true); try { // 从 URL 中获取 sso 和 sig 参数 - const url = new URL(window.location.href); - const sso = url.searchParams.get("sso"); - const sig = url.searchParams.get("sig"); + const sso = searchParams?.get("sso"); + const sig = searchParams?.get("sig"); if (!sso || !sig) { throw new Error("缺少必要的认证参数"); @@ -48,7 +48,7 @@ export function UserAuthorize({ setError(error); setIsLoading(false); } - }, [isLoading, router]); + }, [isLoading, router, searchParams]); useEffect(() => { signInCallback();