import { cookies, headers } from "next/headers"; import Hex from "crypto-js/enc-hex"; import hmacSHA256 from "crypto-js/hmac-sha256"; import WordArray from "crypto-js/lib-typedarrays"; import { AUTH_NONCE } from "@/lib/constants"; 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) { const nonce = WordArray.random(16).toString(); const referer = headers().get("referer") || ""; const url = new URL(referer); const searchParams = url.searchParams.toString(); // 保存原始的 OAuth 参数到 cookie,用于后续重定向 if (searchParams) { cookies().set("oauth_params", searchParams, { maxAge: 60 * 10, // 10分钟过期 path: "/", }); } // 设置 SSO 回调地址,将 OAuth 参数编码后传递 const return_url = searchParams ? `${hostUrl}/authorize?${searchParams}` // 直接将 OAuth 参数附加到回调 URL : `${hostUrl}/dashboard`; // 如果没有 OAuth 参数,回到仪表板 const sso = btoa( `nonce=${nonce}&return_sso_url=${encodeURIComponent(return_url)}`, ); const sig = hmacSHA256(sso, clientSecret).toString(Hex); cookies().set(AUTH_NONCE, nonce, { maxAge: 60 * 10 }); return Response.json({ sso_url: `${discourseHost}/session/sso_provider?sso=${sso}&sig=${sig}`, }); }