From a85c15381a6b3bde4584b731172f9af4a1341452 Mon Sep 17 00:00:00 2001 From: wood chen Date: Fri, 21 Feb 2025 13:25:05 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9B=9E=E5=BD=92=E5=8E=9F=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/api/auth/q58/route.ts | 43 ++++++-------------------- src/components/auth/user-auth-form.tsx | 37 +++++----------------- 2 files changed, 16 insertions(+), 64 deletions(-) diff --git a/src/app/api/auth/q58/route.ts b/src/app/api/auth/q58/route.ts index d37097f..07eb483 100644 --- a/src/app/api/auth/q58/route.ts +++ b/src/app/api/auth/q58/route.ts @@ -1,5 +1,3 @@ -"use server"; - import { cookies } from "next/headers"; import Hex from "crypto-js/enc-hex"; import hmacSHA256 from "crypto-js/hmac-sha256"; @@ -11,37 +9,14 @@ const hostUrl = process.env.NEXT_PUBLIC_HOST_URL as string; const discourseHost = process.env.DISCOURSE_HOST as string; const clientSecret = process.env.DISCOURSE_SECRET as string; -export async function POST(req: Request) { - try { - const nonce = WordArray.random(16).toString(); - const url = new URL(req.url); +export async function POST(_req: Request) { + const nonce = WordArray.random(16).toString(); + const return_url = `${hostUrl}/authorize`; + const sso = btoa(`nonce=${nonce}&return_sso_url=${return_url}`); + const sig = hmacSHA256(sso, clientSecret).toString(Hex); - // 从请求中获取原始的 OAuth 参数 - const searchParams = new URLSearchParams(await req.text()); - const oauth = searchParams.get("oauth") || ""; - - // 构建回调 URL - const callbackUrl = new URL("/q58/callback", hostUrl); - if (oauth) { - callbackUrl.searchParams.set("oauth", oauth); - } - - // 构建 SSO 参数 - const ssoParams = new URLSearchParams(); - ssoParams.set("nonce", nonce); - ssoParams.set("return_sso_url", callbackUrl.toString()); - - const sso = btoa(ssoParams.toString()); - const sig = hmacSHA256(sso, clientSecret).toString(Hex); - - // 设置 nonce cookie - cookies().set(AUTH_NONCE, nonce, { maxAge: 60 * 10 }); - - return Response.json({ - sso_url: `${discourseHost}/session/sso_provider?sso=${sso}&sig=${sig}`, - }); - } catch (error) { - console.error("SSO URL generation error:", error); - return Response.json({ error: "Internal server error" }, { status: 500 }); - } + cookies().set(AUTH_NONCE, nonce, { maxAge: 60 * 10 }); + return Response.json({ + sso_url: `${discourseHost}/session/sso_provider?sso=${sso}&sig=${sig}`, + }); } diff --git a/src/components/auth/user-auth-form.tsx b/src/components/auth/user-auth-form.tsx index 8ea7da9..de3ad1d 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, useSearchParams } from "next/navigation"; +import { useRouter } from "next/navigation"; import { Loader2, MessageCircleCode } from "lucide-react"; import { cn } from "@/lib/utils"; @@ -19,43 +19,20 @@ export function UserAuthForm({ const [isLoading, setIsLoading] = React.useState(false); const router = useRouter(); const { toast } = useToast(); - const searchParams = useSearchParams(); const signIn = () => { React.startTransition(async () => { - try { - // 获取当前的 OAuth 参数 - const params = new URLSearchParams(); - if (searchParams) { - const keys = Array.from(searchParams.keys()); - keys.forEach((key) => { - const value = searchParams.get(key); - if (value) params.set(key, value); - }); - } - - const response = await fetch("/api/auth/q58", { - method: "POST", - body: params, - }); - - if (!response.ok) { - throw new Error(response.statusText); - } - - const data: DiscourseData = await response.json(); - if (data.sso_url) { - router.push(data.sso_url); - } else { - throw new Error("Invalid SSO URL"); - } - } catch (error) { + const response = await fetch("/api/auth/q58", { method: "POST" }); + if (!response.ok || response.status !== 200) { setIsLoading(false); toast({ variant: "destructive", title: "内部服务异常", - description: error instanceof Error ? error.message : "未知错误", + description: response.statusText, }); + } else { + let data: DiscourseData = await response.json(); + router.push(data.sso_url); } }); };