feat: 增加 OAuth 支持,优化用户授权流程,简化参数处理和错误显示

This commit is contained in:
wood chen 2025-02-21 17:22:56 +08:00
parent 3b47daccee
commit 6c8bda6b32
2 changed files with 77 additions and 46 deletions

View File

@ -4,10 +4,21 @@ import { redirect } from "next/navigation";
import { signIn as nextSignIn } from "@/auth"; import { signIn as nextSignIn } from "@/auth";
export async function signIn(data: Record<string, any>) { export async function signIn(data: Record<string, any>) {
const { sso, sig } = data; const { sso, sig, oauth } = data;
// 先进行 SSO 登录
await nextSignIn("credentials", { sso, sig }); await nextSignIn("credentials", { sso, sig });
// 从 sso 参数中获取 return_sso_url // 如果有 OAuth 参数,重定向到 OAuth 授权页面
if (oauth) {
const oauthParams = new URLSearchParams(atob(oauth));
if (oauthParams.has("client_id")) {
const authUrl = `/oauth/authorize?${oauthParams.toString()}`;
redirect(authUrl);
}
}
// 如果没有 OAuth 参数,从 SSO 参数中获取 return_sso_url
const params = new URLSearchParams(atob(sso)); const params = new URLSearchParams(atob(sso));
const returnUrl = params.get("return_sso_url"); const returnUrl = params.get("return_sso_url");

View File

@ -23,24 +23,45 @@ export function UserAuthorize({
} }
setIsLoading(true); setIsLoading(true);
try { try {
await signIn({ ...data, redirectTo: "/dashboard" }); // 从 URL 中获取 sso 和 sig 参数
const url = new URL(window.location.href);
const sso = url.searchParams.get("sso");
const sig = url.searchParams.get("sig");
if (!sso || !sig) {
throw new Error("缺少必要的认证参数");
}
// 获取原始的 OAuth 参数
const originalOAuthParams = new URLSearchParams(window.location.search);
const oauthData: Record<string, string> = {};
Array.from(originalOAuthParams.entries())
.filter(([key]) => key !== "sso" && key !== "sig")
.forEach(([key, value]) => {
oauthData[key] = value;
});
// 传递 SSO 参数和原始的 OAuth 参数
await signIn({
sso,
sig,
oauth: btoa(originalOAuthParams.toString()),
});
setIsLoading(false); setIsLoading(false);
} catch (error) { } catch (error) {
console.error("登录过程出错:", error);
setError(error); setError(error);
setIsLoading(false); setIsLoading(false);
} }
}, []); }, [isLoading]);
useEffect(() => { useEffect(() => {
const timer = setTimeout(signInCallback, 5); signInCallback();
return () => { }, [signInCallback]);
clearTimeout(timer);
};
}, []);
if (error) {
return ( return (
<>
{error ? (
<Card className="w-full"> <Card className="w-full">
<CardHeader className="space-y-4 text-center"> <CardHeader className="space-y-4 text-center">
<div className="mx-auto flex h-16 w-16 items-center justify-center rounded-full bg-red-100"> <div className="mx-auto flex h-16 w-16 items-center justify-center rounded-full bg-red-100">
@ -58,15 +79,16 @@ export function UserAuthorize({
</p> </p>
</CardContent> </CardContent>
</Card> </Card>
) : ( );
}
return (
<Card className="w-full"> <Card className="w-full">
<CardHeader className="space-y-4 text-center"> <CardHeader className="space-y-4 text-center">
<div className="mx-auto flex h-16 w-16 items-center justify-center rounded-full bg-blue-100"> <div className="mx-auto flex h-16 w-16 items-center justify-center rounded-full bg-blue-100">
<div className="h-8 w-8 animate-spin rounded-full border-4 border-blue-600 border-t-transparent"></div> <div className="h-8 w-8 animate-spin rounded-full border-4 border-blue-600 border-t-transparent"></div>
</div> </div>
<CardTitle className="text-2xl font-semibold"> <CardTitle className="text-2xl font-semibold"></CardTitle>
</CardTitle>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<p className="text-center text-gray-500"> <p className="text-center text-gray-500">
@ -74,7 +96,5 @@ export function UserAuthorize({
</p> </p>
</CardContent> </CardContent>
</Card> </Card>
)}
</>
); );
} }