mirror of
https://github.com/woodchen-ink/Q58Connect.git
synced 2025-07-18 14:01:55 +08:00
refactor: Simplify OAuth authorization page and component with direct SSO handling
This commit is contained in:
parent
a3e43bf9e1
commit
a05bce4e38
@ -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>
|
||||
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -62,7 +62,7 @@ export function UserAuthForm({
|
||||
) : (
|
||||
<MessageCircleCode className="mr-2 size-4" />
|
||||
)}{" "}
|
||||
Q58
|
||||
Q58论坛
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user