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,58 +23,78 @@ 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 (
<Card className="w-full">
<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="h-8 w-8 text-red-600"></div>
</div>
<CardTitle className="text-2xl font-semibold text-red-600">
</CardTitle>
</CardHeader>
<CardContent>
<p className="text-center text-gray-500">
{error instanceof Error
? error.message
: "登录异常,授权失败!请稍后重试。"}
</p>
</CardContent>
</Card>
);
}
return ( return (
<> <Card className="w-full">
{error ? ( <CardHeader className="space-y-4 text-center">
<Card className="w-full"> <div className="mx-auto flex h-16 w-16 items-center justify-center rounded-full bg-blue-100">
<CardHeader className="space-y-4 text-center"> <div className="h-8 w-8 animate-spin rounded-full border-4 border-blue-600 border-t-transparent"></div>
<div className="mx-auto flex h-16 w-16 items-center justify-center rounded-full bg-red-100"> </div>
<div className="h-8 w-8 text-red-600"></div> <CardTitle className="text-2xl font-semibold"></CardTitle>
</div> </CardHeader>
<CardTitle className="text-2xl font-semibold text-red-600"> <CardContent>
<p className="text-center text-gray-500">
</CardTitle> {isLoading ? "请稍候,我们正在处理您的授权请求" : "正在跳转..."}
</CardHeader> </p>
<CardContent> </CardContent>
<p className="text-center text-gray-500"> </Card>
{error instanceof Error
? error.message
: "登录异常,授权失败!请稍后重试。"}
</p>
</CardContent>
</Card>
) : (
<Card className="w-full">
<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="h-8 w-8 animate-spin rounded-full border-4 border-blue-600 border-t-transparent"></div>
</div>
<CardTitle className="text-2xl font-semibold">
</CardTitle>
</CardHeader>
<CardContent>
<p className="text-center text-gray-500">
{isLoading ? "请稍候,我们正在处理您的授权请求" : "正在跳转..."}
</p>
</CardContent>
</Card>
)}
</>
); );
} }