refactor: Simplify OAuth authorization page and component with direct SSO handling

This commit is contained in:
wood chen 2025-02-21 19:19:11 +08:00
parent a3e43bf9e1
commit a05bce4e38
4 changed files with 50 additions and 70 deletions

View File

@ -32,7 +32,7 @@ export default function LoginPage() {
<MessageCircleCode className="mx-auto size-12" />
<div className="text-2xl font-semibold tracking-tight">
<span>Welcome to</span>{" "}
<span style={{ fontFamily: "Bahamas Bold" }}>Q58论坛 Connect</span>
<span style={{ fontFamily: "Bahamas Bold" }}>Q58 Connect</span>
</div>
</div>
<Suspense>

View File

@ -6,18 +6,19 @@ import { Authorizing } from "@/components/auth/authorizing";
import { ErrorCard } from "@/components/auth/error-card";
export interface AuthorizeParams {
scope?: string;
response_type: string;
client_id: string;
redirect_uri: string;
scope?: string;
state?: string;
}
export default async function AuthorizePage({
export default async function OAuthAuthorization({
searchParams,
}: {
searchParams: AuthorizeParams;
}) {
// 检查用户是否已登录
const user = await getCurrentUser();
if (!user?.id) {
redirect("/sign-in");
@ -57,6 +58,7 @@ export default async function AuthorizePage({
);
}
// 验证客户端
const client = await getClientByClientId(searchParams.client_id);
if (!client) {
return (
@ -102,25 +104,10 @@ export default async function AuthorizePage({
);
}
// 构建 OAuth 参数
const oauthParams = new URLSearchParams();
oauthParams.set("response_type", searchParams.response_type);
oauthParams.set("client_id", searchParams.client_id);
oauthParams.set("redirect_uri", searchParams.redirect_uri);
if (searchParams.scope) oauthParams.set("scope", searchParams.scope);
if (searchParams.state) oauthParams.set("state", searchParams.state);
// 转换参数格式
const authorizeParams = {
oauth: btoa(oauthParams.toString()),
clientId: client.id,
scope: searchParams.scope || "read_profile",
redirectUri: searchParams.redirect_uri,
};
// 使用原始的 Authorizing 组件处理授权流程
return (
<div className="flex min-h-screen items-center justify-center p-4">
<Authorizing {...authorizeParams} />
<div className="flex min-h-screen items-center justify-center bg-gray-50 p-4">
<Authorizing />
</div>
);
}

View File

@ -1,67 +1,60 @@
"use client";
import { useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { handleAuthorizeAction } from "@/actions/authorizing";
import { useCallback, useEffect, useState } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import { getDiscourseSSOUrl } from "@/actions/discourse-sso-url";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { ErrorCard } from "@/components/auth/error-card";
interface AuthorizingProps {
oauth: string;
clientId: string;
scope: string;
redirectUri: string;
}
export function Authorizing({
oauth,
clientId,
scope,
redirectUri,
}: AuthorizingProps) {
const [error, setError] = useState<string | null>(null);
export function Authorizing() {
const router = useRouter();
const searchParams = useSearchParams();
const [error, setError] = useState<unknown | null>(null);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
const authorize = async () => {
const signInCallback = useCallback(async () => {
try {
const result = await handleAuthorizeAction(oauth, clientId, scope);
if (result.error) {
setError(result.error);
} else if (result.redirectUrl) {
const url = await result.redirectUrl;
window.location.href = url;
} else {
setError("授权响应无效");
}
} catch (err) {
console.error("授权过程出错:", err);
setError(err instanceof Error ? err.message : "授权过程发生未知错误");
} finally {
const url = await getDiscourseSSOUrl(searchParams.toString());
router.push(url);
} catch (error) {
setError(error);
setIsLoading(false);
}
};
}, [router, searchParams]);
authorize();
}, [oauth, clientId, scope]);
useEffect(() => {
// Delay 3s get sso url go to ...
const timer = setTimeout(signInCallback, 3);
return () => {
clearTimeout(timer);
};
}, [signInCallback]);
if (error) {
return (
<div className="flex min-h-screen items-center justify-center p-4">
<ErrorCard
title="授权失败"
description={error}
redirectUri={redirectUri}
error="access_denied"
errorDescription={error}
/>
<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 (
<Card className="w-full max-w-md">
<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>

View File

@ -62,7 +62,7 @@ export function UserAuthForm({
) : (
<MessageCircleCode className="mr-2 size-4" />
)}{" "}
Q58
Q58论坛
</button>
</div>
);